mirror of
https://github.com/certd/certd.git
synced 2026-04-24 04:17:25 +08:00
chore:
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
require('./lib/node_loader')
|
||||
module.exports = require('./lib/core')
|
||||
@@ -0,0 +1 @@
|
||||
module.exports.DomainService = require("./repo/domainservice/v2/domainservice.js");
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require('./lib/jc')
|
||||
@@ -0,0 +1,4 @@
|
||||
require("babel-polyfill");
|
||||
require("./browser_loader");
|
||||
var JC = require("./core");
|
||||
module.exports = JC;
|
||||
@@ -0,0 +1,13 @@
|
||||
var util = require('./util')
|
||||
util.crypto.lib = {
|
||||
createHash: require('create-hash'),
|
||||
createHmac: require('create-hmac')
|
||||
}
|
||||
util.Buffer = require('buffer/').Buffer
|
||||
util.url = require('url/')
|
||||
util.querystring = require('querystring/')
|
||||
util.environment = 'js'
|
||||
|
||||
var JC = require('./core')
|
||||
|
||||
module.exports = JC
|
||||
@@ -0,0 +1,6 @@
|
||||
require('./core')
|
||||
|
||||
require('./config')
|
||||
require('./request')
|
||||
require('./service')
|
||||
require('./credentials')
|
||||
@@ -0,0 +1,78 @@
|
||||
var JDCloud = require('./core')
|
||||
|
||||
let defaultValues = {
|
||||
credentials: null,
|
||||
regionId: null,
|
||||
apiVersions: null,
|
||||
endpoint: {},
|
||||
version: {},
|
||||
logger: function (string, level = 'INFO') {
|
||||
// level: INFO / DEBUG / ERROR / WARN
|
||||
console.log(string)
|
||||
}
|
||||
}
|
||||
JDCloud.Config = class Config {
|
||||
constructor (options = {}) {
|
||||
options = this.extractCredentials(options)
|
||||
|
||||
JDCloud.util.each.call(this, defaultValues, function (key, value) {
|
||||
if (options[key] === undefined) {
|
||||
this[key] = value
|
||||
} else {
|
||||
this[key] = options[key]
|
||||
}
|
||||
})
|
||||
JDCloud.util.each.call(this, JDCloud.Service._services, function (
|
||||
key,
|
||||
value
|
||||
) {
|
||||
if (options[key] !== undefined) {
|
||||
this[key] = options[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
extractCredentials (options) {
|
||||
if (options.accessKeyId && options.secretAccessKey) {
|
||||
options = Object.assign({}, options)
|
||||
options.credentials = new JDCloud.Credentials(options)
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
getCredentials () {
|
||||
var p = new Promise((resolve, reject) => {
|
||||
if (this.credentials) {
|
||||
if (typeof this.credentials.get === 'function') {
|
||||
} else if (
|
||||
this.credentials.accessKeyId &&
|
||||
this.credentials.secretAccessKey
|
||||
) {
|
||||
resolve()
|
||||
} else {
|
||||
reject(new Error('missing credentials'))
|
||||
}
|
||||
} else if (this.credentialProvider) {
|
||||
} else {
|
||||
reject(new Error('get credentials failed'))
|
||||
}
|
||||
})
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
update (options, allowUnknownKeys = false) {
|
||||
options = this.extractCredentials(options)
|
||||
JDCloud.util.each.call(this, options, function (key, value) {
|
||||
if (
|
||||
allowUnknownKeys ||
|
||||
defaultValues.hasOwnProperty(key) ||
|
||||
JDCloud.Service.hasService(key)
|
||||
) {
|
||||
this[key] = options[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
JDCloud.config = new JDCloud.Config()
|
||||
@@ -0,0 +1,13 @@
|
||||
require('node-fetch')
|
||||
|
||||
var JDCloud = {
|
||||
util: require('./util'),
|
||||
// todo swaggerVar
|
||||
VERSION: ''
|
||||
}
|
||||
|
||||
module.exports = JDCloud
|
||||
|
||||
require('./service')
|
||||
require('./config')
|
||||
require('./request')
|
||||
@@ -0,0 +1,21 @@
|
||||
var JDCloud = require('./core')
|
||||
|
||||
JDCloud.Credentials = class Credentials {
|
||||
constructor () {
|
||||
this.expired = false
|
||||
this.expireTime = null
|
||||
|
||||
if (arguments.length === 1 && typeof arguments[0] === 'object') {
|
||||
var creds = arguments[0].credentials || arguments[0]
|
||||
this.accessKeyId = creds.accessKeyId
|
||||
this.secretAccessKey = creds.secretAccessKey
|
||||
this.sessionToken = creds.sessionToken
|
||||
} else {
|
||||
this.accessKeyId = arguments[0]
|
||||
this.secretAccessKey = arguments[1]
|
||||
this.sessionToken = arguments[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = JDCloud.Credentials
|
||||
@@ -0,0 +1,3 @@
|
||||
require('./node_loader')
|
||||
var JDCloud = require('./core')
|
||||
module.exports = JDCloud
|
||||
@@ -0,0 +1,12 @@
|
||||
var util = require('./util')
|
||||
|
||||
util.crypto.lib = require('crypto')
|
||||
util.Buffer = require('buffer').Buffer
|
||||
util.url = require('url')
|
||||
util.querystring = require('querystring')
|
||||
util.environment = 'nodejs'
|
||||
let JDCloud = require('./core')
|
||||
JDCloud.fetch = require('node-fetch')
|
||||
module.exports = JDCloud
|
||||
|
||||
require('./credentials')
|
||||
@@ -0,0 +1,159 @@
|
||||
var JDCloud = require('./core')
|
||||
|
||||
let util = JDCloud.util
|
||||
JDCloud.JCRequest = class JCRequest {
|
||||
constructor (
|
||||
service,
|
||||
path,
|
||||
httpMethod,
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType
|
||||
) {
|
||||
this.service = service
|
||||
|
||||
var endpoint = service.config.endpoint
|
||||
pathParams.regionId = pathParams.regionId || service.config.regionId
|
||||
this.regionId = pathParams.regionId
|
||||
|
||||
this.path = this.buildPath(path, pathParams)
|
||||
this.path = util.uriEscapePath(this.path)
|
||||
|
||||
var queryString = this.buildQuery(queryParams)
|
||||
|
||||
var url = this.path
|
||||
if (queryString) {
|
||||
url = this.path + '?' + queryString
|
||||
}
|
||||
|
||||
var contentType = this.jsonPreferredMime(contentTypes) || 'application/json'
|
||||
headerParams['content-type'] = contentType
|
||||
var requestHeaders = this.buildHeaders(headerParams)
|
||||
|
||||
var requestInit = {
|
||||
method: httpMethod || 'GET',
|
||||
headers: requestHeaders
|
||||
}
|
||||
|
||||
if (contentType === 'application/x-www-form-urlencoded') {
|
||||
} else if (contentType === 'multipart/form-data') {
|
||||
} else if (postBody) {
|
||||
requestInit.body = JSON.stringify(postBody)
|
||||
}
|
||||
var fetchUrl = endpoint.protocol + '://' + endpoint.host + url
|
||||
JDCloud.config.logger(
|
||||
`make request where url is :${fetchUrl} \nwith fetch config:${JSON.stringify(
|
||||
requestInit
|
||||
)}`
|
||||
)
|
||||
this.request = new JDCloud.fetch.Request(fetchUrl, requestInit)
|
||||
}
|
||||
|
||||
buildPath (path, pathParams) {
|
||||
var uri = (this.service.config.basePath || '') + path
|
||||
uri = uri.replace(/\{([\w-]+)\}/g, (fullMatch, key) => {
|
||||
var value
|
||||
if (pathParams.hasOwnProperty(key)) {
|
||||
value = pathParams[key]
|
||||
} else {
|
||||
value = fullMatch
|
||||
}
|
||||
return value
|
||||
})
|
||||
return uri
|
||||
}
|
||||
|
||||
buildQuery (queryParams) {
|
||||
var queryParamsWithoutEmptyItem = {}
|
||||
var keys = Object.keys(queryParams)
|
||||
for (let key of keys) {
|
||||
if (queryParams[key] !== undefined) {
|
||||
queryParamsWithoutEmptyItem[key] = queryParams[key]
|
||||
}
|
||||
}
|
||||
return JDCloud.util.querystring.stringify(queryParamsWithoutEmptyItem)
|
||||
}
|
||||
|
||||
search () {
|
||||
var query = this.request.url.split('?', 2)[1]
|
||||
if (query) {
|
||||
query = JDCloud.util.querystring.parse(query)
|
||||
return JDCloud.util.queryParamsToString(query)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
digitizationArray (key, obj) {
|
||||
var result = key
|
||||
if (Array.isArray(obj)) {
|
||||
JDCloud.util.arrayEach(obj, (arrayValue, index) => {
|
||||
result += this.digitizationArray(`.${index + 1}`, arrayValue)
|
||||
})
|
||||
} else if (typeof obj === 'object' && obj != null) {
|
||||
JDCloud.util.each(obj, (key, ObjValue) => {
|
||||
result += `.name=${key}&${result}.values` + this.digitizationArray()
|
||||
result +=
|
||||
key +
|
||||
'.name=' +
|
||||
ObjValue +
|
||||
'&' +
|
||||
this.digitizationArray(key + '.values', ObjValue)
|
||||
})
|
||||
} else {
|
||||
result += key + '=' + encodeURI(obj)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
buildHeaders (headerParams) {
|
||||
var headers = new JDCloud.fetch.Headers({
|
||||
accept: 'application/json'
|
||||
})
|
||||
|
||||
util.each.call(this, headerParams, function (key) {
|
||||
if (headerParams[key] !== undefined && headerParams[key] != null) {
|
||||
headers.append(key, headerParams[key])
|
||||
}
|
||||
})
|
||||
return headers
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given content type represents JSON.<br>
|
||||
* JSON content type examples:<br>
|
||||
* <ul>
|
||||
* <li>application/json</li>
|
||||
* <li>application/json; charset=UTF8</li>
|
||||
* <li>APPLICATION/JSON</li>
|
||||
* </ul>
|
||||
* @param {String} contentType The MIME content type to check.
|
||||
* @returns {Boolean} <code>true</code> if <code>contentType</code> represents JSON, otherwise <code>false</code>.
|
||||
*/
|
||||
isJsonMime (contentType) {
|
||||
return Boolean(
|
||||
contentType != null && contentType.match(/^application\/json(;.*)?$/i)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Chooses a content type from the given array, with JSON preferred; i.e. return JSON if included, otherwise return the first.
|
||||
* @param {Array.<String>} contentTypes
|
||||
* @returns {String} The chosen content type, preferring JSON.
|
||||
*/
|
||||
jsonPreferredMime (contentTypes) {
|
||||
for (var i = 0; i < contentTypes.length; i++) {
|
||||
if (this.isJsonMime(contentTypes[i])) {
|
||||
return contentTypes[i]
|
||||
}
|
||||
}
|
||||
|
||||
return contentTypes[0]
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = JDCloud.JCRequest
|
||||
@@ -0,0 +1,231 @@
|
||||
var JDCloud = require('./core')
|
||||
var SignerV2 = require('./signers/v2')
|
||||
|
||||
JDCloud.Service = class Service {
|
||||
constructor (serviceId, config = {}) {
|
||||
this.serviceId = serviceId
|
||||
this.init(config)
|
||||
}
|
||||
|
||||
init (config) {
|
||||
// 某个服务类型的全局配置
|
||||
var serviceConfig = JDCloud.config[this.serviceId]
|
||||
// 全局配置
|
||||
this.config = new JDCloud.Config(JDCloud.config)
|
||||
if (serviceConfig) {
|
||||
this.config.update(serviceConfig, true)
|
||||
}
|
||||
if (config) {
|
||||
if (!this.config.endpoint.host && !config.endpoint) {
|
||||
config.endpoint = config._defaultEndpoint
|
||||
}
|
||||
delete config._defaultEndpoint
|
||||
this.config.update(config, true)
|
||||
}
|
||||
}
|
||||
|
||||
makeRequest (
|
||||
path,
|
||||
httpMethod,
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType,
|
||||
callback
|
||||
) {
|
||||
var request = new JDCloud.JCRequest(
|
||||
this,
|
||||
path,
|
||||
httpMethod,
|
||||
pathParams,
|
||||
queryParams,
|
||||
headerParams,
|
||||
formParams,
|
||||
postBody,
|
||||
contentTypes,
|
||||
accepts,
|
||||
returnType
|
||||
)
|
||||
|
||||
var signer = new SignerV2(request, this.serviceId)
|
||||
|
||||
return this.config.getCredentials().then(() => {
|
||||
signer.addAuthorization(this.config.credentials)
|
||||
return JDCloud.fetch(signer.request.request).then(response => {
|
||||
return response.json().then(
|
||||
result => {
|
||||
result.responseObj = response
|
||||
if (response.ok) {
|
||||
return result
|
||||
}
|
||||
return Promise.reject(result)
|
||||
},
|
||||
error => {
|
||||
error.responseObj = response
|
||||
if (error.type === 'invalid-json') {
|
||||
// oss没有返回json
|
||||
if (response.ok) {
|
||||
return Promise.resolve({
|
||||
requestId: response.headers.get('x-jdcloud-request-id') || ''
|
||||
})
|
||||
} else {
|
||||
/* eslint-disable */
|
||||
return Promise.reject({
|
||||
requestId: response.headers.get('x-jdcloud-request-id') || ''
|
||||
})
|
||||
/* eslint-enable */
|
||||
}
|
||||
}
|
||||
throw error
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
buildCollectionParam (param, collectionFormat) {
|
||||
if (param === null || param === undefined) {
|
||||
return param
|
||||
}
|
||||
switch (collectionFormat) {
|
||||
case 'csv':
|
||||
return param.map(this.paramToString).join(',')
|
||||
case 'ssv':
|
||||
return param.map(this.paramToString).join(' ')
|
||||
case 'tsv':
|
||||
return param.map(this.paramToString).join('\t')
|
||||
case 'pipes':
|
||||
return param.map(this.paramToString).join('|')
|
||||
case 'multi':
|
||||
// return the array directly as SuperAgent will handle it as expected
|
||||
return param.map(this.paramToString)
|
||||
default:
|
||||
throw new Error('Unknown collection format: ' + collectionFormat)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* filter is a special type of array
|
||||
* only contains:
|
||||
* [
|
||||
* { name: someString , values:[ someString, someString ] ,operator: someString}
|
||||
* ]
|
||||
*
|
||||
*/
|
||||
buildFilterParam (param, key) {
|
||||
var result = {}
|
||||
if (Array.isArray(param)) {
|
||||
let index = 0
|
||||
for (var i = 0; i < param.length; i++) {
|
||||
var obj = param[i]
|
||||
|
||||
// 兼容空字符串
|
||||
if (obj.values !== '' && !Array.isArray(obj.values)) {
|
||||
throw new Error('The type of filters.values should be Array!')
|
||||
}
|
||||
if (obj.name && obj.values) {
|
||||
if (!obj.values.length) continue
|
||||
result[`${key}.${index + 1}.name`] = obj.name
|
||||
for (var j = 0; j < obj.values.length; j++) {
|
||||
var someString = obj.values[j]
|
||||
result[`${key}.${index + 1}.values.${j + 1}`] = someString
|
||||
}
|
||||
if (obj.operator) {
|
||||
result[`${key}.${index + 1}.operator`] = obj.operator
|
||||
}
|
||||
index++
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
buildTagFilterParam (param = [], key) {
|
||||
var result = {}
|
||||
if (!Array.isArray(param)) {
|
||||
throw new Error(`The type of param 'param' should be Array!`)
|
||||
}
|
||||
|
||||
for (var i = 0; i < param.length; i++) {
|
||||
var obj = param[i]
|
||||
|
||||
if (obj.values && !Array.isArray(obj.values)) {
|
||||
throw new Error(
|
||||
`The type of param 'param[${i}].values' should be Array or NULL!`
|
||||
)
|
||||
}
|
||||
|
||||
if (obj.key) {
|
||||
result[`${key}.${i + 1}.key`] = obj.key
|
||||
|
||||
if (obj.values) {
|
||||
for (var j = 0; j < obj.values.length; j++) {
|
||||
var someString = obj.values[j]
|
||||
result[`${key}.${i + 1}.values.${j + 1}`] = someString
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
buildSortParam (param = [], key) {
|
||||
var result = {}
|
||||
if (!Array.isArray(param)) {
|
||||
throw new Error(`The type of param 'param' should be Array!`)
|
||||
}
|
||||
|
||||
var index = 0
|
||||
for (var i = 0; i < param.length; i++) {
|
||||
var obj = param[i]
|
||||
|
||||
if (obj.name && obj.direction) {
|
||||
index++
|
||||
result[`${key}.${index}.name`] = obj.name
|
||||
result[`${key}.${index}.direction`] = obj.direction
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// arr=[a,b,c] => arr={arr1:a, arr2:b, arr3:c}
|
||||
buildArrayParam (param = [], key) {
|
||||
var result = {}
|
||||
if (!Array.isArray(param)) {
|
||||
throw new Error(`The type of param 'param' should be Array!`)
|
||||
}
|
||||
|
||||
for (var i = 0; i < param.length; i++) {
|
||||
var value = param[i]
|
||||
result[`${key}.${i + 1}`] = value
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation for an actual parameter.
|
||||
* @param param The actual parameter.
|
||||
* @returns {String} The string representation of <code>param</code>.
|
||||
*/
|
||||
paramToString (param) {
|
||||
if (param === undefined || param === null) {
|
||||
return ''
|
||||
}
|
||||
if (param instanceof Date) {
|
||||
return param.toJSON()
|
||||
}
|
||||
|
||||
return param.toString()
|
||||
}
|
||||
|
||||
static hasService (id) {
|
||||
return JDCloud.Service._services.hasOwnProperty(id)
|
||||
}
|
||||
}
|
||||
JDCloud.Service._services = {}
|
||||
|
||||
module.exports = JDCloud.Service
|
||||
@@ -0,0 +1,13 @@
|
||||
module.exports = class RequestSigner {
|
||||
constructor (request) {
|
||||
this.request = request
|
||||
}
|
||||
|
||||
setServiceClientId (id) {
|
||||
this.serviceClientId = id
|
||||
}
|
||||
|
||||
getServiceClientId () {
|
||||
return this.serviceClientId
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
// Copyright 2018 JDCLOUD.COM
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License
|
||||
// This signer is modified from AWS V4 signer algorithm.
|
||||
|
||||
var util = require("../util");
|
||||
var RequestSigner = require("./request_signer");
|
||||
var v2Credentials = require("./v2_credentials");
|
||||
var uuid = require("uuid");
|
||||
var JDCloud = require("../core");
|
||||
|
||||
module.exports = class SignerV2 extends RequestSigner {
|
||||
constructor(request, serviceName, options = {}) {
|
||||
super(request);
|
||||
this.signatureCache = true;
|
||||
this.algorithm = "JDCLOUD2-HMAC-SHA256";
|
||||
this.unsignableHeaders = ["authorization", "user-agent"];
|
||||
this.serviceName = serviceName;
|
||||
// this.signatureCache = typeof options.signatureCache === 'boolean' ? options.signatureCache : true;
|
||||
}
|
||||
|
||||
// 签名流程见 https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
|
||||
|
||||
addAuthorization(credentials, date) {
|
||||
// var datetime = '20180119T070300Z';
|
||||
var datetime = util.date.iso8601(date).replace(/[:-]|\.\d{3}/g, "");
|
||||
this.addHeaders(credentials, datetime);
|
||||
this.request.request.headers.set("Authorization", this.authorization(credentials, datetime));
|
||||
}
|
||||
|
||||
addHeaders(credentials, datetime) {
|
||||
this.request.request.headers.set("x-jdcloud-date", datetime);
|
||||
this.request.request.headers.set("x-jdcloud-nonce", uuid.v4());
|
||||
this.request.request.headers.set("host", this.request.service.config.endpoint.host);
|
||||
}
|
||||
|
||||
signedHeaders() {
|
||||
var keys = [];
|
||||
this.request.request.headers.forEach((value, key) => {
|
||||
key = key.toLowerCase();
|
||||
if (this.isSignableHeader(key)) {
|
||||
keys.push(key);
|
||||
}
|
||||
});
|
||||
/* util.each.call(this, this.request.headers, function (key) {
|
||||
|
||||
}); */
|
||||
return keys.sort().join(";");
|
||||
}
|
||||
|
||||
credentialString(datetime) {
|
||||
return v2Credentials.createScope(datetime.substr(0, 8), this.request.regionId, this.serviceName);
|
||||
}
|
||||
|
||||
signature(credentials, datetime) {
|
||||
var signingKey = v2Credentials.getSigningKey(credentials, datetime.substr(0, 8), this.request.regionId, this.serviceName, this.signatureCache);
|
||||
return util.crypto.hmac(signingKey, this.stringToSign(datetime), "hex");
|
||||
}
|
||||
|
||||
stringToSign(datetime) {
|
||||
var parts = [];
|
||||
parts.push(this.algorithm);
|
||||
parts.push(datetime);
|
||||
parts.push(this.credentialString(datetime));
|
||||
parts.push(this.hexEncodedHash(this.canonicalString()));
|
||||
JDCloud.config.logger("StringToSign is \n" + JSON.stringify(parts), "DEBUG");
|
||||
return parts.join("\n");
|
||||
}
|
||||
|
||||
// 构建标准签名字符串
|
||||
canonicalString() {
|
||||
var parts = [];
|
||||
var pathname = this.request.path;
|
||||
// if (this.serviceName !== 'jfs') {
|
||||
// pathname = util.uriEscapePath(pathname)
|
||||
// }
|
||||
|
||||
parts.push(this.request.request.method);
|
||||
parts.push(pathname);
|
||||
parts.push(this.request.search());
|
||||
parts.push(this.canonicalHeaders() + "\n");
|
||||
parts.push(this.signedHeaders());
|
||||
parts.push(this.hexEncodedBodyHash());
|
||||
JDCloud.config.logger("canonicalString is \n" + JSON.stringify(parts), "DEBUG");
|
||||
return parts.join("\n");
|
||||
}
|
||||
|
||||
canonicalHeaders() {
|
||||
var headers = [];
|
||||
this.request.request.headers.forEach((value, key) => {
|
||||
headers.push([key, value]);
|
||||
});
|
||||
headers.sort(function (a, b) {
|
||||
return a[0].toLowerCase() < b[0].toLowerCase() ? -1 : 1;
|
||||
});
|
||||
var parts = [];
|
||||
util.arrayEach.call(this, headers, function (item) {
|
||||
var key = item[0].toLowerCase();
|
||||
if (this.isSignableHeader(key)) {
|
||||
var value = item[1];
|
||||
if (typeof value === "undefined" || value === null || typeof value.toString !== "function") {
|
||||
throw util.error(new Error("Header " + key + " contains invalid value"), {
|
||||
code: "InvalidHeader",
|
||||
});
|
||||
}
|
||||
parts.push(key + ":" + this.canonicalHeaderValues(value.toString()));
|
||||
}
|
||||
});
|
||||
return parts.join("\n");
|
||||
}
|
||||
|
||||
canonicalHeaderValues(values) {
|
||||
return values.replace(/\s+/g, " ").replace(/^\s+|\s+$/g, "");
|
||||
}
|
||||
|
||||
authorization(credentials, datetime) {
|
||||
var parts = [];
|
||||
var credString = this.credentialString(datetime);
|
||||
parts.push(this.algorithm + " Credential=" + credentials.accessKeyId + "/" + credString);
|
||||
parts.push("SignedHeaders=" + this.signedHeaders());
|
||||
parts.push("Signature=" + this.signature(credentials, datetime));
|
||||
JDCloud.config.logger("Signature is \n" + JSON.stringify(parts), "DEBUG");
|
||||
return parts.join(", ");
|
||||
}
|
||||
|
||||
hexEncodedHash(string) {
|
||||
return util.crypto.sha256(string, "hex");
|
||||
}
|
||||
|
||||
hexEncodedBodyHash() {
|
||||
return this.hexEncodedHash(this.request.request.body || "");
|
||||
/* var request = this.request;
|
||||
if (this.isPresigned() && this.serviceName === 's3' && !request.body) {
|
||||
return 'UNSIGNED-PAYLOAD';
|
||||
} else if (request.headers['X-Amz-Content-Sha256']) {
|
||||
return request.headers['X-Amz-Content-Sha256'];
|
||||
} else {
|
||||
return this.hexEncodedHash(this.request.body || '');
|
||||
} */
|
||||
}
|
||||
|
||||
isSignableHeader(key) {
|
||||
if (key.toLowerCase().includes("x-jdcloud-")) {
|
||||
return true;
|
||||
}
|
||||
return !this.unsignableHeaders.includes(key.toLowerCase());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,80 @@
|
||||
var cachedSecret = {}
|
||||
var cacheQueue = []
|
||||
var maxCacheEntries = 50
|
||||
var v2Identifier = 'jdcloud2_request'
|
||||
|
||||
var util = require('../util')
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* @api private
|
||||
*
|
||||
* @param date [String]
|
||||
* @param region [String]
|
||||
* @param serviceName [String]
|
||||
* @return [String]
|
||||
*/
|
||||
createScope: function createScope (date, region, serviceName) {
|
||||
return [date.substr(0, 8), region, serviceName, v2Identifier].join('/')
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*
|
||||
* @param credentials [Credentials]
|
||||
* @param date [String]
|
||||
* @param region [String]
|
||||
* @param service [String]
|
||||
* @param shouldCache [Boolean]
|
||||
* @return [String]
|
||||
*/
|
||||
getSigningKey: function getSigningKey (
|
||||
credentials,
|
||||
date,
|
||||
region,
|
||||
service,
|
||||
shouldCache
|
||||
) {
|
||||
var credsIdentifier = util.crypto.hmac(
|
||||
credentials.secretAccessKey,
|
||||
credentials.accessKeyId,
|
||||
'base64'
|
||||
)
|
||||
var cacheKey = [credsIdentifier, date, region, service].join('_')
|
||||
shouldCache = shouldCache !== false
|
||||
if (shouldCache && cacheKey in cachedSecret) {
|
||||
return cachedSecret[cacheKey]
|
||||
}
|
||||
|
||||
var kDate = util.crypto.hmac(
|
||||
'JDCLOUD2' + credentials.secretAccessKey,
|
||||
date,
|
||||
'buffer'
|
||||
)
|
||||
var kRegion = util.crypto.hmac(kDate, region, 'buffer')
|
||||
var kService = util.crypto.hmac(kRegion, service, 'buffer')
|
||||
|
||||
var signingKey = util.crypto.hmac(kService, v2Identifier, 'buffer')
|
||||
if (shouldCache) {
|
||||
cachedSecret[cacheKey] = signingKey
|
||||
cacheQueue.push(cacheKey)
|
||||
if (cacheQueue.length > maxCacheEntries) {
|
||||
// remove the oldest entry (not the least recently used)
|
||||
delete cachedSecret[cacheQueue.shift()]
|
||||
}
|
||||
}
|
||||
|
||||
return signingKey
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*
|
||||
* Empties the derived signing key cache. Made available for testing purposes
|
||||
* only.
|
||||
*/
|
||||
emptyCache: function emptyCache () {
|
||||
cachedSecret = {}
|
||||
cacheQueue = []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,477 @@
|
||||
var util = {
|
||||
isBrowser: function isBrowser () {
|
||||
return process && process.browser
|
||||
},
|
||||
isNode: function isNode () {
|
||||
return !util.isBrowser()
|
||||
},
|
||||
uriEscape: function uriEscape (string) {
|
||||
var output = encodeURIComponent(string)
|
||||
output = output.replace(/[^A-Za-z0-9_.~\-%]+/g, escape)
|
||||
|
||||
// AWS percent-encodes some extra non-standard characters in a URI
|
||||
output = output.replace(/[*]/g, function (ch) {
|
||||
return (
|
||||
'%' +
|
||||
ch
|
||||
.charCodeAt(0)
|
||||
.toString(16)
|
||||
.toUpperCase()
|
||||
)
|
||||
})
|
||||
|
||||
return output
|
||||
},
|
||||
uriEscapePath: function uriEscapePath (string) {
|
||||
var parts = []
|
||||
util.arrayEach(string.split('/'), function (part) {
|
||||
parts.push(util.uriEscape(part))
|
||||
})
|
||||
return parts.join('/')
|
||||
},
|
||||
abort: {},
|
||||
each: function each (object, iterFunction) {
|
||||
for (var key in object) {
|
||||
if (Object.prototype.hasOwnProperty.call(object, key)) {
|
||||
var ret = iterFunction.call(this, key, object[key])
|
||||
if (ret === util.abort) break
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
arrayEach: function arrayEach (array, iterFunction) {
|
||||
for (var idx in array) {
|
||||
if (Object.prototype.hasOwnProperty.call(array, idx)) {
|
||||
var ret = iterFunction.call(this, array[idx], parseInt(idx, 10))
|
||||
if (ret === util.abort) break
|
||||
}
|
||||
}
|
||||
},
|
||||
arraySliceFn: function arraySliceFn (obj) {
|
||||
var fn = obj.slice || obj.webkitSlice || obj.mozSlice
|
||||
return typeof fn === 'function' ? fn : null
|
||||
},
|
||||
queryParamsToString: function queryParamsToString (params) {
|
||||
var items = []
|
||||
var escape = util.uriEscape
|
||||
var sortedKeys = Object.keys(params).sort()
|
||||
|
||||
util.arrayEach(sortedKeys, function (name) {
|
||||
var value = params[name]
|
||||
var ename = escape(name)
|
||||
var result = ename + '='
|
||||
if (Array.isArray(value)) {
|
||||
var vals = []
|
||||
util.arrayEach(value, function (item) {
|
||||
vals.push(escape(item))
|
||||
})
|
||||
result = ename + '=' + vals.sort().join('&' + ename + '=')
|
||||
} else if (value !== undefined && value !== null) {
|
||||
result = ename + '=' + escape(value)
|
||||
}
|
||||
items.push(result)
|
||||
})
|
||||
|
||||
return items.join('&')
|
||||
},
|
||||
date: {
|
||||
getDate () {
|
||||
return new Date()
|
||||
},
|
||||
iso8601: function iso8601 (date) {
|
||||
if (date === undefined) {
|
||||
date = util.date.getDate()
|
||||
}
|
||||
return date.toISOString().replace(/\.\d{3}Z$/, 'Z')
|
||||
}
|
||||
},
|
||||
crypto: {
|
||||
/* eslint-disable no-use-before-define */
|
||||
crc32Table: [
|
||||
0x00000000,
|
||||
0x77073096,
|
||||
0xee0e612c,
|
||||
0x990951ba,
|
||||
0x076dc419,
|
||||
0x706af48f,
|
||||
0xe963a535,
|
||||
0x9e6495a3,
|
||||
0x0edb8832,
|
||||
0x79dcb8a4,
|
||||
0xe0d5e91e,
|
||||
0x97d2d988,
|
||||
0x09b64c2b,
|
||||
0x7eb17cbd,
|
||||
0xe7b82d07,
|
||||
0x90bf1d91,
|
||||
0x1db71064,
|
||||
0x6ab020f2,
|
||||
0xf3b97148,
|
||||
0x84be41de,
|
||||
0x1adad47d,
|
||||
0x6ddde4eb,
|
||||
0xf4d4b551,
|
||||
0x83d385c7,
|
||||
0x136c9856,
|
||||
0x646ba8c0,
|
||||
0xfd62f97a,
|
||||
0x8a65c9ec,
|
||||
0x14015c4f,
|
||||
0x63066cd9,
|
||||
0xfa0f3d63,
|
||||
0x8d080df5,
|
||||
0x3b6e20c8,
|
||||
0x4c69105e,
|
||||
0xd56041e4,
|
||||
0xa2677172,
|
||||
0x3c03e4d1,
|
||||
0x4b04d447,
|
||||
0xd20d85fd,
|
||||
0xa50ab56b,
|
||||
0x35b5a8fa,
|
||||
0x42b2986c,
|
||||
0xdbbbc9d6,
|
||||
0xacbcf940,
|
||||
0x32d86ce3,
|
||||
0x45df5c75,
|
||||
0xdcd60dcf,
|
||||
0xabd13d59,
|
||||
0x26d930ac,
|
||||
0x51de003a,
|
||||
0xc8d75180,
|
||||
0xbfd06116,
|
||||
0x21b4f4b5,
|
||||
0x56b3c423,
|
||||
0xcfba9599,
|
||||
0xb8bda50f,
|
||||
0x2802b89e,
|
||||
0x5f058808,
|
||||
0xc60cd9b2,
|
||||
0xb10be924,
|
||||
0x2f6f7c87,
|
||||
0x58684c11,
|
||||
0xc1611dab,
|
||||
0xb6662d3d,
|
||||
0x76dc4190,
|
||||
0x01db7106,
|
||||
0x98d220bc,
|
||||
0xefd5102a,
|
||||
0x71b18589,
|
||||
0x06b6b51f,
|
||||
0x9fbfe4a5,
|
||||
0xe8b8d433,
|
||||
0x7807c9a2,
|
||||
0x0f00f934,
|
||||
0x9609a88e,
|
||||
0xe10e9818,
|
||||
0x7f6a0dbb,
|
||||
0x086d3d2d,
|
||||
0x91646c97,
|
||||
0xe6635c01,
|
||||
0x6b6b51f4,
|
||||
0x1c6c6162,
|
||||
0x856530d8,
|
||||
0xf262004e,
|
||||
0x6c0695ed,
|
||||
0x1b01a57b,
|
||||
0x8208f4c1,
|
||||
0xf50fc457,
|
||||
0x65b0d9c6,
|
||||
0x12b7e950,
|
||||
0x8bbeb8ea,
|
||||
0xfcb9887c,
|
||||
0x62dd1ddf,
|
||||
0x15da2d49,
|
||||
0x8cd37cf3,
|
||||
0xfbd44c65,
|
||||
0x4db26158,
|
||||
0x3ab551ce,
|
||||
0xa3bc0074,
|
||||
0xd4bb30e2,
|
||||
0x4adfa541,
|
||||
0x3dd895d7,
|
||||
0xa4d1c46d,
|
||||
0xd3d6f4fb,
|
||||
0x4369e96a,
|
||||
0x346ed9fc,
|
||||
0xad678846,
|
||||
0xda60b8d0,
|
||||
0x44042d73,
|
||||
0x33031de5,
|
||||
0xaa0a4c5f,
|
||||
0xdd0d7cc9,
|
||||
0x5005713c,
|
||||
0x270241aa,
|
||||
0xbe0b1010,
|
||||
0xc90c2086,
|
||||
0x5768b525,
|
||||
0x206f85b3,
|
||||
0xb966d409,
|
||||
0xce61e49f,
|
||||
0x5edef90e,
|
||||
0x29d9c998,
|
||||
0xb0d09822,
|
||||
0xc7d7a8b4,
|
||||
0x59b33d17,
|
||||
0x2eb40d81,
|
||||
0xb7bd5c3b,
|
||||
0xc0ba6cad,
|
||||
0xedb88320,
|
||||
0x9abfb3b6,
|
||||
0x03b6e20c,
|
||||
0x74b1d29a,
|
||||
0xead54739,
|
||||
0x9dd277af,
|
||||
0x04db2615,
|
||||
0x73dc1683,
|
||||
0xe3630b12,
|
||||
0x94643b84,
|
||||
0x0d6d6a3e,
|
||||
0x7a6a5aa8,
|
||||
0xe40ecf0b,
|
||||
0x9309ff9d,
|
||||
0x0a00ae27,
|
||||
0x7d079eb1,
|
||||
0xf00f9344,
|
||||
0x8708a3d2,
|
||||
0x1e01f268,
|
||||
0x6906c2fe,
|
||||
0xf762575d,
|
||||
0x806567cb,
|
||||
0x196c3671,
|
||||
0x6e6b06e7,
|
||||
0xfed41b76,
|
||||
0x89d32be0,
|
||||
0x10da7a5a,
|
||||
0x67dd4acc,
|
||||
0xf9b9df6f,
|
||||
0x8ebeeff9,
|
||||
0x17b7be43,
|
||||
0x60b08ed5,
|
||||
0xd6d6a3e8,
|
||||
0xa1d1937e,
|
||||
0x38d8c2c4,
|
||||
0x4fdff252,
|
||||
0xd1bb67f1,
|
||||
0xa6bc5767,
|
||||
0x3fb506dd,
|
||||
0x48b2364b,
|
||||
0xd80d2bda,
|
||||
0xaf0a1b4c,
|
||||
0x36034af6,
|
||||
0x41047a60,
|
||||
0xdf60efc3,
|
||||
0xa867df55,
|
||||
0x316e8eef,
|
||||
0x4669be79,
|
||||
0xcb61b38c,
|
||||
0xbc66831a,
|
||||
0x256fd2a0,
|
||||
0x5268e236,
|
||||
0xcc0c7795,
|
||||
0xbb0b4703,
|
||||
0x220216b9,
|
||||
0x5505262f,
|
||||
0xc5ba3bbe,
|
||||
0xb2bd0b28,
|
||||
0x2bb45a92,
|
||||
0x5cb36a04,
|
||||
0xc2d7ffa7,
|
||||
0xb5d0cf31,
|
||||
0x2cd99e8b,
|
||||
0x5bdeae1d,
|
||||
0x9b64c2b0,
|
||||
0xec63f226,
|
||||
0x756aa39c,
|
||||
0x026d930a,
|
||||
0x9c0906a9,
|
||||
0xeb0e363f,
|
||||
0x72076785,
|
||||
0x05005713,
|
||||
0x95bf4a82,
|
||||
0xe2b87a14,
|
||||
0x7bb12bae,
|
||||
0x0cb61b38,
|
||||
0x92d28e9b,
|
||||
0xe5d5be0d,
|
||||
0x7cdcefb7,
|
||||
0x0bdbdf21,
|
||||
0x86d3d2d4,
|
||||
0xf1d4e242,
|
||||
0x68ddb3f8,
|
||||
0x1fda836e,
|
||||
0x81be16cd,
|
||||
0xf6b9265b,
|
||||
0x6fb077e1,
|
||||
0x18b74777,
|
||||
0x88085ae6,
|
||||
0xff0f6a70,
|
||||
0x66063bca,
|
||||
0x11010b5c,
|
||||
0x8f659eff,
|
||||
0xf862ae69,
|
||||
0x616bffd3,
|
||||
0x166ccf45,
|
||||
0xa00ae278,
|
||||
0xd70dd2ee,
|
||||
0x4e048354,
|
||||
0x3903b3c2,
|
||||
0xa7672661,
|
||||
0xd06016f7,
|
||||
0x4969474d,
|
||||
0x3e6e77db,
|
||||
0xaed16a4a,
|
||||
0xd9d65adc,
|
||||
0x40df0b66,
|
||||
0x37d83bf0,
|
||||
0xa9bcae53,
|
||||
0xdebb9ec5,
|
||||
0x47b2cf7f,
|
||||
0x30b5ffe9,
|
||||
0xbdbdf21c,
|
||||
0xcabac28a,
|
||||
0x53b39330,
|
||||
0x24b4a3a6,
|
||||
0xbad03605,
|
||||
0xcdd70693,
|
||||
0x54de5729,
|
||||
0x23d967bf,
|
||||
0xb3667a2e,
|
||||
0xc4614ab8,
|
||||
0x5d681b02,
|
||||
0x2a6f2b94,
|
||||
0xb40bbe37,
|
||||
0xc30c8ea1,
|
||||
0x5a05df1b,
|
||||
0x2d02ef8d
|
||||
],
|
||||
/* eslint-disable no-use-before-define */
|
||||
|
||||
crc32: function crc32 (data) {
|
||||
var tbl = util.crypto.crc32Table
|
||||
var crc = 0 ^ -1
|
||||
|
||||
if (typeof data === 'string') {
|
||||
data = new util.Buffer(data)
|
||||
}
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var code = data.readUInt8(i)
|
||||
crc = (crc >>> 8) ^ tbl[(crc ^ code) & 0xff]
|
||||
}
|
||||
return (crc ^ -1) >>> 0
|
||||
},
|
||||
|
||||
hmac: function hmac (key, string, digest, fn) {
|
||||
if (!digest) digest = 'binary'
|
||||
if (digest === 'buffer') {
|
||||
digest = undefined
|
||||
}
|
||||
if (!fn) fn = 'sha256'
|
||||
if (typeof string === 'string') string = new util.Buffer(string)
|
||||
return util.crypto.lib
|
||||
.createHmac(fn, key)
|
||||
.update(string)
|
||||
.digest(digest)
|
||||
},
|
||||
|
||||
md5: function md5 (data, digest, callback) {
|
||||
return util.crypto.hash('md5', data, digest, callback)
|
||||
},
|
||||
|
||||
sha256: function sha256 (data, digest, callback) {
|
||||
return util.crypto.hash('sha256', data, digest, callback)
|
||||
},
|
||||
|
||||
hash: function (algorithm, data, digest, callback) {
|
||||
var hash = util.crypto.createHash(algorithm)
|
||||
if (!digest) {
|
||||
digest = 'binary'
|
||||
}
|
||||
if (digest === 'buffer') {
|
||||
digest = undefined
|
||||
}
|
||||
if (typeof data === 'string') data = new util.Buffer(data)
|
||||
var sliceFn = util.arraySliceFn(data)
|
||||
var isBuffer = util.Buffer.isBuffer(data)
|
||||
// Identifying objects with an ArrayBuffer as buffers
|
||||
if (
|
||||
util.isBrowser() &&
|
||||
typeof ArrayBuffer !== 'undefined' &&
|
||||
data &&
|
||||
data.buffer instanceof ArrayBuffer
|
||||
) {
|
||||
isBuffer = true
|
||||
}
|
||||
|
||||
if (
|
||||
callback &&
|
||||
typeof data === 'object' &&
|
||||
typeof data.on === 'function' &&
|
||||
!isBuffer
|
||||
) {
|
||||
data.on('data', function (chunk) {
|
||||
hash.update(chunk)
|
||||
})
|
||||
data.on('error', function (err) {
|
||||
callback(err)
|
||||
})
|
||||
data.on('end', function () {
|
||||
callback(null, hash.digest(digest))
|
||||
})
|
||||
} else if (
|
||||
callback &&
|
||||
sliceFn &&
|
||||
!isBuffer &&
|
||||
typeof FileReader !== 'undefined'
|
||||
) {
|
||||
// this might be a File/Blob
|
||||
var index = 0
|
||||
var size = 1024 * 512
|
||||
var reader = new FileReader()
|
||||
reader.onerror = function () {
|
||||
callback(new Error('Failed to read data.'))
|
||||
}
|
||||
reader.onload = function () {
|
||||
var buf = new util.Buffer(new Uint8Array(reader.result))
|
||||
hash.update(buf)
|
||||
index += buf.length
|
||||
reader._continueReading()
|
||||
}
|
||||
reader._continueReading = function () {
|
||||
if (index >= data.size) {
|
||||
callback(null, hash.digest(digest))
|
||||
return
|
||||
}
|
||||
|
||||
var back = index + size
|
||||
if (back > data.size) back = data.size
|
||||
reader.readAsArrayBuffer(sliceFn.call(data, index, back))
|
||||
}
|
||||
|
||||
reader._continueReading()
|
||||
} else {
|
||||
if (util.isBrowser() && typeof data === 'object' && !isBuffer) {
|
||||
data = new util.Buffer(new Uint8Array(data))
|
||||
}
|
||||
var out = hash.update(data).digest(digest)
|
||||
if (callback) callback(null, out)
|
||||
return out
|
||||
}
|
||||
},
|
||||
|
||||
toHex: function toHex (data) {
|
||||
var out = []
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
out.push(('0' + data.charCodeAt(i).toString(16)).substr(-2, 2))
|
||||
}
|
||||
return out.join('')
|
||||
},
|
||||
|
||||
createHash: function createHash (algorithm) {
|
||||
return util.crypto.lib.createHash(algorithm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = util
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user