From 09965d5eb6dc6d5e82887fdbabac32569adc80b2 Mon Sep 17 00:00:00 2001 From: zhl Date: Fri, 21 Apr 2023 10:13:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=88=86=E5=8F=91=E5=BE=BD?= =?UTF-8?q?=E7=AB=A0=E7=9A=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/chain.controllers.ts | 13 +++++ src/models/ChainTask.ts | 17 ++++++- src/service/info.service.ts | 10 ++-- src/utils/security.util.ts | 74 ++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 src/utils/security.util.ts diff --git a/src/controllers/chain.controllers.ts b/src/controllers/chain.controllers.ts index 90c7e99..cda2090 100644 --- a/src/controllers/chain.controllers.ts +++ b/src/controllers/chain.controllers.ts @@ -4,6 +4,8 @@ import { ChainTask, ChainTaskClass } from 'models/ChainTask' import { RequestTask } from 'models/RequestTask' import { ChainQueue } from 'queue/chain.queue' import { DocumentType } from '@typegoose/typegoose' +import { BlockChain } from 'chain/BlockChain' +import { ZError } from 'common/ZError' class ChainController extends BaseController { @role('anon') @@ -32,5 +34,16 @@ class ChainController extends BaseController { await chainTask.save() return chainTask.toJson() } + + @role('anon') + @router('post /chain/query_info') + async queryUserInfo(req, res) { + let { address } = req.params + if (!address) { + throw new ZError(10, 'address is required') + } + let info = await new BlockChain().distributorReactor.getMintableCount({ user: address }) + return { count: info } + } } export default ChainController diff --git a/src/models/ChainTask.ts b/src/models/ChainTask.ts index c7422ae..bcdc132 100644 --- a/src/models/ChainTask.ts +++ b/src/models/ChainTask.ts @@ -61,6 +61,7 @@ export class ChainTaskClass extends BaseModule { let record = await ChainTask.findById(chainTaskId) let sCount = 0 let errCount = 0 + let hashList: string[] = [] for (let subId of record.tasks) { let subData = await RequestTask.findById(subId) if (subData.status === ReqTaskStatus.SUCCESS) { @@ -68,6 +69,7 @@ export class ChainTaskClass extends BaseModule { } else if (subData.status === ReqTaskStatus.ERROR) { errCount += 1 } + hashList.push(subData.txHash) } record.successCount = sCount record.errorCount = errCount @@ -88,7 +90,20 @@ export class ChainTaskClass extends BaseModule { } await record.save() if (record.allEnd) { - setImmediate(async function () {}) + setImmediate(async function () { + try { + let result = await new InfoSvr().reportTaskResult({ + id: record.taskId, + result: record.status, + successCount: record.successCount, + errorCount: record.errorCount, + hashList, + }) + logger.log(result) + } catch (err) { + logger.log(err) + } + }) } } diff --git a/src/service/info.service.ts b/src/service/info.service.ts index d73b0bd..24e73ac 100644 --- a/src/service/info.service.ts +++ b/src/service/info.service.ts @@ -1,13 +1,17 @@ import axios from 'axios' import { singleton } from 'decorators/singleton' import logger from 'logger/logger' +import { hmacSha256 } from 'utils/security.util' -const REPORT_TASK_URI = '/api/flow/client/result' +const REPORT_TASK_URI = '/api/internal/update_task' +const calcHash = function (data: any) { + return hmacSha256(JSON.stringify(data), process.env.HASH_SALT) +} @singleton export class InfoSvr { - reportTaskResult(data) { - data.user = process.env.RUN_USER + reportTaskResult(data: any) { + data.sign = calcHash(data) logger.info('report to info svr: ' + JSON.stringify(data)) let url = `${process.env.INFO_SVR_HOST}${REPORT_TASK_URI}` let reqConfig: any = { diff --git a/src/utils/security.util.ts b/src/utils/security.util.ts new file mode 100644 index 0000000..8ddf5a4 --- /dev/null +++ b/src/utils/security.util.ts @@ -0,0 +1,74 @@ +import crypto from 'crypto' + +export function hmac(input, key, out) { + return out + ? crypto.createHmac('sha1', key).update(input).digest(out) + : crypto.createHmac('sha1', key).update(input).digest('hex') +} + +export function genRandomString(length) { + return crypto + .randomBytes(Math.ceil(length / 2)) + .toString('hex') + .slice(0, length) +} + +export function sha512(password, salt) { + let hash = crypto.createHmac('sha512', salt) + hash.update(password) + let value = hash.digest('hex') + return { + salt: salt, + passwordHash: value, + } +} + +export function sha1(str) { + const md5sum = crypto.createHash('sha1') + md5sum.update(str) + str = md5sum.digest('hex') + return str +} + +export function hmacSha256(str: string, key: any) { + const md5sum = crypto.createHmac('sha256', key) + md5sum.update(str) + str = md5sum.digest('hex') + return str +} + +export function md5(str) { + const md5sum = crypto.createHash('md5') + md5sum.update(str) + str = md5sum.digest('hex') + return str +} + +export function createSign(secretKey, paramStr, timestamp) { + paramStr = `${paramStr}:${timestamp}:${secretKey}` + return sha1(paramStr) +} + +export function checkSign({ + secretKey, + data, + sign, + signKeys, +}: { + secretKey: string + data: {} + sign: string + signKeys: string[] +}) { + signKeys.sort() + let signStr = '' + for (let key of signKeys) { + if (signStr.length > 0) { + signStr += '&' + } + signStr += `${key}=${data[key]}` + } + console.log(signStr) + let sign1 = hmacSha256(signStr, secretKey) + return sign1 === sign +}