mirror of https://github.com/certd/certd
chore:
parent
8ecc2f9446
commit
f9a3ac2cb1
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"prettier"
|
||||
],
|
||||
"env": {
|
||||
"mocha": true
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
test/user.secret.ts
|
||||
|
||||
.rollup.cache
|
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
src
|
||||
.rollup.cache
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printWidth": 160
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.24.3](https://github.com/certd/certd/compare/v1.24.2...v1.24.3) (2024-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.24.2](https://github.com/certd/certd/compare/v1.24.1...v1.24.2) (2024-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.24.1](https://github.com/certd/certd/compare/v1.24.0...v1.24.1) (2024-09-02)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19)
|
||||
|
||||
### Features
|
||||
|
||||
* 升级midway,支持esm ([485e603](https://github.com/certd/certd/commit/485e603b5165c28bc08694997726eaf2a585ebe7))
|
||||
* 支持postgresql ([3b19bfb](https://github.com/certd/certd/commit/3b19bfb4291e89064b3b407a80dae092d54747d5))
|
|
@ -0,0 +1,16 @@
|
|||
# Vue 3 + TypeScript + Vite
|
||||
|
||||
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
|
||||
|
||||
## Type Support For `.vue` Imports in TS
|
||||
|
||||
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's Take Over mode by following these steps:
|
||||
|
||||
1. Run `Extensions: Show Built-in Extensions` from VS Code's command palette, look for `TypeScript and JavaScript Language Features`, then right click and select `Disable (Workspace)`. By default, Take Over mode will enable itself if the default TypeScript extension is disabled.
|
||||
2. Reload the VS Code window by running `Developer: Reload Window` from the command palette.
|
||||
|
||||
You can learn more about Take Over mode [here](https://github.com/johnsoncodehk/volar/discussions/471).
|
|
@ -0,0 +1,96 @@
|
|||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
// https://gist.github.com/lovasoa/8691344
|
||||
async function* walk(dir) {
|
||||
for await (const d of await fs.promises.opendir(dir)) {
|
||||
const entry = path.join(dir, d.name);
|
||||
if (d.isDirectory()) {
|
||||
yield* walk(entry);
|
||||
} else if (d.isFile()) {
|
||||
yield entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resolveImportPath(sourceFile, importPath, options) {
|
||||
const sourceFileAbs = path.resolve(process.cwd(), sourceFile);
|
||||
const root = path.dirname(sourceFileAbs);
|
||||
const { moduleFilter = defaultModuleFilter } = options;
|
||||
|
||||
if (moduleFilter(importPath)) {
|
||||
const importPathAbs = path.resolve(root, importPath);
|
||||
let possiblePath = [path.resolve(importPathAbs, "./index.ts"), path.resolve(importPathAbs, "./index.js"), importPathAbs + ".ts", importPathAbs + ".js"];
|
||||
|
||||
if (possiblePath.length) {
|
||||
for (let i = 0; i < possiblePath.length; i++) {
|
||||
let entry = possiblePath[i];
|
||||
if (fs.existsSync(entry)) {
|
||||
const resolved = path.relative(root, entry.replace(/\.ts$/, ".js"));
|
||||
|
||||
if (!resolved.startsWith(".")) {
|
||||
return "./" + resolved;
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function replace(filePath, outFilePath, options) {
|
||||
const code = fs.readFileSync(filePath).toString();
|
||||
const newCode = code.replace(/(import|export) (.+?) from ('[^\n']+'|"[^\n"]+");/gs, function (found, action, imported, from) {
|
||||
const importPath = from.slice(1, -1);
|
||||
let resolvedPath = resolveImportPath(filePath, importPath, options);
|
||||
|
||||
if (resolvedPath) {
|
||||
resolvedPath = resolvedPath.replaceAll("\\", "/");
|
||||
console.log("\t", importPath, resolvedPath);
|
||||
return `${action} ${imported} from "${resolvedPath}";`;
|
||||
}
|
||||
|
||||
return found;
|
||||
});
|
||||
|
||||
if (code !== newCode) {
|
||||
fs.writeFileSync(outFilePath, newCode);
|
||||
}
|
||||
}
|
||||
|
||||
// Then, use it with a simple async for loop
|
||||
async function run(srcDir, options = defaultOptions) {
|
||||
const { sourceFileFilter = defaultSourceFileFilter } = options;
|
||||
|
||||
for await (const entry of walk(srcDir)) {
|
||||
if (sourceFileFilter(entry)) {
|
||||
console.log(entry);
|
||||
replace(entry, entry, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const defaultSourceFileFilter = function (sourceFilePath) {
|
||||
return /\.(js|ts)$/.test(sourceFilePath) && !/node_modules/.test(sourceFilePath);
|
||||
};
|
||||
|
||||
const defaultModuleFilter = function (importedModule) {
|
||||
return !path.isAbsolute(importedModule) && !importedModule.startsWith("@") && !importedModule.endsWith(".js");
|
||||
};
|
||||
|
||||
const defaultOptions = {
|
||||
sourceFileFilter: defaultSourceFileFilter,
|
||||
moduleFilter: defaultModuleFilter,
|
||||
};
|
||||
|
||||
// Switch this to test on one file or directly run on a directory.
|
||||
const DEBUG = false;
|
||||
|
||||
if (DEBUG) {
|
||||
replace("./src/index.ts", "./out.ts", defaultOptions);
|
||||
} else {
|
||||
await run("./src/", defaultOptions);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "@certd/lib-jdcloud",
|
||||
"private": false,
|
||||
"version": "1.24.4",
|
||||
"main": "./dist/bundle.mjs",
|
||||
"module": "./dist/bundle.mjs",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "rollup -c ",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/pipeline": "1.21.0",
|
||||
"axios": "^1.7.2",
|
||||
"node-fetch": "^3.3.2",
|
||||
"rollup": "^3.7.4",
|
||||
"uuid": "^3.4.0"
|
||||
},
|
||||
"gitHead": "c49ccbde93dbad7062ac39d4f18eca7d561f573f"
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
const resolve = require("@rollup/plugin-node-resolve");
|
||||
const commonjs = require("@rollup/plugin-commonjs");
|
||||
//const Typescript = require("rollup-plugin-typescript2");
|
||||
const Typescript = require("@rollup/plugin-typescript");
|
||||
const json = require("@rollup/plugin-json");
|
||||
const terser = require("@rollup/plugin-terser");
|
||||
module.exports = {
|
||||
input: "src/index.js",
|
||||
output: {
|
||||
file: "dist/bundle.mjs",
|
||||
format: "es",
|
||||
},
|
||||
plugins: [
|
||||
// 解析第三方依赖
|
||||
resolve(),
|
||||
// 识别 commonjs 模式第三方依赖
|
||||
commonjs({
|
||||
// dynamicRequireRoot: "../../../../",
|
||||
// dynamicRequireTargets: [
|
||||
// // include using a glob pattern (either a string or an array of strings)
|
||||
// "../../../../**/shelljs/src/*",
|
||||
// ],
|
||||
}),
|
||||
// Typescript({
|
||||
// target: "esnext",
|
||||
// rootDir: "src",
|
||||
// declaration: true,
|
||||
// declarationDir: "dist/d",
|
||||
// exclude: ["./node_modules/**", "./src/**/*.vue", "./src/**/*.spec.ts"],
|
||||
// allowSyntheticDefaultImports: true,
|
||||
// }),
|
||||
json(),
|
||||
terser(),
|
||||
],
|
||||
external: ["vue", "lodash-es", "dayjs", "log4js", "@midwayjs/core", "@certd/pipeline", "axios", "node-fetch"],
|
||||
};
|
|
@ -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
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"inlineSourceMap":true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"stripInternal": true,
|
||||
"skipLibCheck": true,
|
||||
"pretty": true,
|
||||
"declaration": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"typeRoots": [ "./typings", "./node_modules/@types"],
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"composite": true,
|
||||
"useDefineForClassFields": true,
|
||||
"strict": false,
|
||||
"sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": false,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.d.ts",
|
||||
"src/**/*.js",
|
||||
"src/**/*.json"
|
||||
],
|
||||
"exclude": [
|
||||
"*.ts",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"test"
|
||||
],
|
||||
}
|
|
@ -4,6 +4,7 @@ import * as api from "./api";
|
|||
// @ts-ignore
|
||||
import _ from "lodash-es";
|
||||
import { toRef } from "vue";
|
||||
import { useReference } from "/@/use/use-refrence";
|
||||
|
||||
export function getCommonColumnDefine(crudExpose: any, typeRef: any) {
|
||||
const AccessTypeDictRef = dict({
|
||||
|
@ -32,19 +33,10 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any) {
|
|||
...value,
|
||||
key
|
||||
};
|
||||
let column = _.merge({ title: key }, defaultPluginConfig, field);
|
||||
const column = _.merge({ title: key }, defaultPluginConfig, field);
|
||||
|
||||
//eval
|
||||
if (column.mergeScript) {
|
||||
const ctx = {
|
||||
compute
|
||||
};
|
||||
const script = column.mergeScript;
|
||||
delete column.mergeScript;
|
||||
const func = new Function("ctx", script);
|
||||
const merged = func(ctx);
|
||||
column = _.merge(column, merged);
|
||||
}
|
||||
useReference(column);
|
||||
|
||||
//设置默认值
|
||||
if (column.value != null && _.get(form, key) == null) {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@certd/acme-client": "^1.24.4",
|
||||
"@certd/lib-huawei": "^1.24.3",
|
||||
"@certd/lib-jdcloud": "^1.24.4",
|
||||
"@certd/lib-k8s": "^1.24.4",
|
||||
"@certd/midway-flyway-js": "^1.24.4",
|
||||
"@certd/pipeline": "^1.24.4",
|
||||
|
@ -62,6 +63,7 @@
|
|||
"md5": "^2.3.0",
|
||||
"mwtsc": "^1.4.0",
|
||||
"nanoid": "^4.0.0",
|
||||
"node-fetch": "^3.3.2",
|
||||
"nodemailer": "^6.9.3",
|
||||
"pg": "^8.12.0",
|
||||
"qiniu": "^7.12.0",
|
||||
|
@ -72,7 +74,8 @@
|
|||
"svg-captcha": "^1.4.0",
|
||||
"syno": "^2.2.0",
|
||||
"tencentcloud-sdk-nodejs": "^4.0.44",
|
||||
"typeorm": "^0.3.20"
|
||||
"typeorm": "^0.3.20",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@midwayjs/mock": "^3.16.4",
|
||||
|
|
|
@ -9,3 +9,4 @@ export * from './plugin-other/index.js';
|
|||
export * from './plugin-west/index.js';
|
||||
export * from './plugin-doge/index.js';
|
||||
export * from './plugin-qiniu/index.js';
|
||||
export * from './plugin-jdcloud/index.js';
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import { AccessInput, IsAccess } from '@certd/pipeline';
|
||||
|
||||
/**
|
||||
* 这个注解将注册一个授权配置
|
||||
* 在certd的后台管理系统中,用户可以选择添加此类型的授权
|
||||
*/
|
||||
@IsAccess({
|
||||
name: 'dynadot',
|
||||
title: 'dynadot授权',
|
||||
desc: '目前设置dns解析会覆盖已有的解析配置,慎用',
|
||||
})
|
||||
export class DynadotAccess {
|
||||
/**
|
||||
* 授权属性配置
|
||||
*/
|
||||
@AccessInput({
|
||||
title: 'API Production Key',
|
||||
component: {
|
||||
placeholder: '授权key',
|
||||
},
|
||||
helper: '前往 [Dynadot API](https://www.dynadot.com/account/domain/setting/api.html) 获取 API Production Key',
|
||||
required: true,
|
||||
encrypt: true,
|
||||
})
|
||||
apiProductionKey = '';
|
||||
}
|
||||
|
||||
new DynadotAccess();
|
|
@ -0,0 +1,85 @@
|
|||
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from '@certd/plugin-cert';
|
||||
import { Autowire, ILogger } from '@certd/pipeline';
|
||||
import { DynadotAccess } from './access.js';
|
||||
import querystring from 'querystring';
|
||||
|
||||
// 这里通过IsDnsProvider注册一个dnsProvider
|
||||
@IsDnsProvider({
|
||||
name: 'dynadot',
|
||||
title: 'dynadot',
|
||||
desc: 'dynadot dns provider',
|
||||
// 这里是对应的 cloudflare的access类型名称
|
||||
accessType: 'dynadot',
|
||||
})
|
||||
export class DynadotDnsProvider extends AbstractDnsProvider {
|
||||
// 通过Autowire传递context
|
||||
@Autowire()
|
||||
logger!: ILogger;
|
||||
access!: DynadotAccess;
|
||||
async onInstance() {
|
||||
this.access = this.ctx.access as DynadotAccess;
|
||||
}
|
||||
|
||||
private async doRequest(command: string, query: any) {
|
||||
const baseUrl = 'https://api.dynadot.com/api3.json?key=' + this.access.apiProductionKey;
|
||||
const qs = querystring.stringify(query);
|
||||
const url = `${baseUrl}&command=${command}&${qs}`;
|
||||
const res = await this.ctx.http.request<any, any>({
|
||||
url,
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
/*
|
||||
"SetDnsResponse": {
|
||||
"ResponseCode": 0,
|
||||
"Status": "success"
|
||||
}
|
||||
*/
|
||||
for (const resKey in res) {
|
||||
if (res[resKey].ResponseCode != null && res[resKey].ResponseCode !== 0) {
|
||||
throw new Error(`请求失败:${res[resKey].Status}`);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建dns解析记录,用于验证域名所有权
|
||||
*/
|
||||
async createRecord(options: CreateRecordOptions) {
|
||||
/**
|
||||
* fullRecord: '_acme-challenge.test.example.com',
|
||||
* value: 一串uuid
|
||||
* type: 'TXT',
|
||||
* domain: 'example.com'
|
||||
*/
|
||||
const { fullRecord, value, type, domain } = options;
|
||||
this.logger.info('添加域名解析:', fullRecord, value, type, domain);
|
||||
|
||||
const prefix = fullRecord.replace(`.${domain}`, '');
|
||||
// 给domain下创建txt类型的dns解析记录,fullRecord
|
||||
const res = await this.doRequest('set_dns2', {
|
||||
domain: domain,
|
||||
subdomain0: prefix,
|
||||
sub_record_type0: 'TXT',
|
||||
sub_record0 : value,
|
||||
});
|
||||
this.logger.info(`添加域名解析成功:fullRecord=${fullRecord},value=${value}`);
|
||||
this.logger.info(`请求结果:${JSON.stringify(res)}`);
|
||||
|
||||
//本接口需要返回本次创建的dns解析记录,这个记录会在删除的时候用到
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除dns解析记录,清理申请痕迹
|
||||
* @param options
|
||||
*/
|
||||
async removeRecord(options: RemoveRecordOptions<any>): Promise<void> {}
|
||||
}
|
||||
|
||||
//实例化这个provider,将其自动注册到系统中
|
||||
new DynadotDnsProvider();
|
|
@ -0,0 +1,3 @@
|
|||
export * from './dns-provider.js';
|
||||
export * from './plugins/index.js';
|
||||
export * from './access.js';
|
|
@ -0,0 +1,39 @@
|
|||
import { AccessInput, IsAccess } from '@certd/pipeline';
|
||||
|
||||
/**
|
||||
* 这个注解将注册一个授权配置
|
||||
* 在certd的后台管理系统中,用户可以选择添加此类型的授权
|
||||
*/
|
||||
@IsAccess({
|
||||
name: 'jdcloud',
|
||||
title: '京东云授权',
|
||||
desc: '目前设置dns解析会覆盖已有的解析配置,慎用',
|
||||
})
|
||||
export class JDCloudAccess {
|
||||
/**
|
||||
* 授权属性配置
|
||||
*/
|
||||
@AccessInput({
|
||||
title: 'AccessKeyId',
|
||||
component: {
|
||||
placeholder: 'AK',
|
||||
},
|
||||
helper: '前往 [AccessKey管理](https://uc.jdcloud.com/account/accesskey) 获取 API Production Key',
|
||||
required: true,
|
||||
encrypt: true,
|
||||
})
|
||||
accessKeyId = '';
|
||||
|
||||
@AccessInput({
|
||||
title: 'AccessKeySecret',
|
||||
component: {
|
||||
placeholder: 'SK',
|
||||
},
|
||||
helper: 'SK',
|
||||
required: true,
|
||||
encrypt: true,
|
||||
})
|
||||
accessKeySecret = '';
|
||||
}
|
||||
|
||||
new JDCloudAccess();
|
|
@ -0,0 +1,111 @@
|
|||
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from '@certd/plugin-cert';
|
||||
import { Autowire, ILogger } from '@certd/pipeline';
|
||||
import { JDCloudAccess } from './access.js';
|
||||
function promisfy(func: any) {
|
||||
return (params: any, regionId: string) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
func(params, regionId, (err, result) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// 这里通过IsDnsProvider注册一个dnsProvider
|
||||
@IsDnsProvider({
|
||||
name: 'jdcloud',
|
||||
title: '京东云',
|
||||
desc: '京东云 dns provider',
|
||||
// 这里是对应的 cloudflare的access类型名称
|
||||
accessType: 'jdcloud',
|
||||
})
|
||||
export class JDCloudDnsProvider extends AbstractDnsProvider {
|
||||
// 通过Autowire传递context
|
||||
@Autowire()
|
||||
logger!: ILogger;
|
||||
access!: JDCloudAccess;
|
||||
service!: any;
|
||||
regionId: string;
|
||||
async onInstance() {
|
||||
this.access = this.ctx.access as JDCloudAccess;
|
||||
const { DomainService } = await import('@certd/lib-jdcloud');
|
||||
// @ts-ignore
|
||||
this.regionId = 'cn-north-1';
|
||||
this.service = new DomainService({
|
||||
credentials: {
|
||||
accessKeyId: this.access.accessKeyId,
|
||||
secretAccessKey: this.access.accessKeySecret,
|
||||
},
|
||||
regionId: this.regionId,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建dns解析记录,用于验证域名所有权
|
||||
*/
|
||||
async createRecord(options: CreateRecordOptions) {
|
||||
/**
|
||||
* fullRecord: '_acme-challenge.test.example.com',
|
||||
* value: 一串uuid
|
||||
* type: 'TXT',
|
||||
* domain: 'example.com'
|
||||
*/
|
||||
const { fullRecord, value, type, domain } = options;
|
||||
this.logger.info('添加域名解析:', fullRecord, value, type, domain);
|
||||
|
||||
const describeDomains = promisfy(this.service.describeDomains);
|
||||
|
||||
const res: any = await describeDomains({ domainName: domain, pageNumber: 1, pageSize: 10 }, this.regionId);
|
||||
|
||||
if (res.dataList.length === 0) {
|
||||
throw new Error('账号下找不到域名:' + domain);
|
||||
}
|
||||
const domainId = res.dataList[0].id;
|
||||
|
||||
//开始创建解析记录
|
||||
const createResourceRecord = promisfy(this.service.createResourceRecord);
|
||||
const res2: any = await createResourceRecord(
|
||||
{
|
||||
domainId,
|
||||
req: {
|
||||
hostRecord: fullRecord,
|
||||
hostValue: value,
|
||||
type: 'TXT',
|
||||
},
|
||||
},
|
||||
this.regionId
|
||||
);
|
||||
|
||||
const recordId = res2.dataList[0].id;
|
||||
|
||||
this.logger.info(`添加域名解析成功:fullRecord=${fullRecord},value=${value}`);
|
||||
this.logger.info(`请求结果:recordId:${recordId}`);
|
||||
|
||||
//本接口需要返回本次创建的dns解析记录,这个记录会在删除的时候用到
|
||||
return { id: recordId, domainId };
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除dns解析记录,清理申请痕迹
|
||||
* @param opts
|
||||
*/
|
||||
async removeRecord(opts: RemoveRecordOptions<any>): Promise<void> {
|
||||
const { record } = opts;
|
||||
const deleteResourceRecord = promisfy(this.service.deleteResourceRecord);
|
||||
const res = await deleteResourceRecord(
|
||||
{
|
||||
domainId: record.domainId,
|
||||
resourceRecordId: record.id,
|
||||
},
|
||||
this.regionId
|
||||
);
|
||||
this.logger.info(`删除dns解析记录成功:${JSON.stringify(res)}`);
|
||||
}
|
||||
}
|
||||
|
||||
//实例化这个provider,将其自动注册到系统中
|
||||
new JDCloudDnsProvider();
|
|
@ -0,0 +1,3 @@
|
|||
export * from './dns-provider.js';
|
||||
export * from './plugins/index.js';
|
||||
export * from './access.js';
|
Loading…
Reference in New Issue