mirror of https://github.com/certd/certd
chore:
parent
6877b865a7
commit
87620b9072
|
@ -72,19 +72,19 @@ export const Constants = {
|
|||
},
|
||||
openKeyError: {
|
||||
code: 20000,
|
||||
message: 'openKey错误',
|
||||
message: 'ApiToken错误',
|
||||
},
|
||||
openKeySignError: {
|
||||
code: 20001,
|
||||
message: 'openKey签名错误',
|
||||
message: 'ApiToken签名错误',
|
||||
},
|
||||
openKeyExpiresError: {
|
||||
code: 20002,
|
||||
message: 'openKey时间戳错误',
|
||||
message: 'ApiToken时间戳错误',
|
||||
},
|
||||
openKeySignTypeError: {
|
||||
code: 20003,
|
||||
message: 'openKey签名类型不支持',
|
||||
message: 'ApiToken签名类型不支持',
|
||||
},
|
||||
openParamError: {
|
||||
code: 20010,
|
||||
|
@ -94,5 +94,9 @@ export const Constants = {
|
|||
code: 20011,
|
||||
message: '证书不存在',
|
||||
},
|
||||
openCertNotReady: {
|
||||
code: 20012,
|
||||
message: '证书还未生成',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
* 异常基类
|
||||
*/
|
||||
export class BaseException extends Error {
|
||||
status: number;
|
||||
code: number;
|
||||
constructor(name, code, message) {
|
||||
super(message);
|
||||
this.name = name;
|
||||
this.status = code;
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ export class Result<T> {
|
|||
}
|
||||
|
||||
static error(code = 1, msg) {
|
||||
return new Result(code, msg, null);
|
||||
return new Result(code, msg);
|
||||
}
|
||||
|
||||
static success(msg, data?) {
|
||||
|
|
|
@ -126,32 +126,6 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
show: false
|
||||
}
|
||||
},
|
||||
"pipeline.title": {
|
||||
title: "已关联流水线",
|
||||
search: { show: false },
|
||||
type: "link",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
width: 280,
|
||||
sorter: true,
|
||||
component: {}
|
||||
}
|
||||
},
|
||||
applyTime: {
|
||||
title: "申请时间",
|
||||
search: {
|
||||
show: false
|
||||
},
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
sorter: true
|
||||
}
|
||||
},
|
||||
expiresTime: {
|
||||
title: "过期时间",
|
||||
search: {
|
||||
|
@ -175,18 +149,6 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
}
|
||||
}
|
||||
},
|
||||
fromType: {
|
||||
title: "来源",
|
||||
search: {
|
||||
show: true
|
||||
},
|
||||
type: "text",
|
||||
form: { show: false },
|
||||
column: {
|
||||
width: 100,
|
||||
sorter: true
|
||||
}
|
||||
},
|
||||
certProvider: {
|
||||
title: "证书颁发机构",
|
||||
search: {
|
||||
|
@ -197,7 +159,33 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
show: false
|
||||
},
|
||||
column: {
|
||||
width: 400
|
||||
width: 200
|
||||
}
|
||||
},
|
||||
applyTime: {
|
||||
title: "申请时间",
|
||||
search: {
|
||||
show: false
|
||||
},
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
sorter: true
|
||||
}
|
||||
},
|
||||
"pipeline.title": {
|
||||
title: "已关联流水线",
|
||||
search: { show: false },
|
||||
type: "link",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
width: 350,
|
||||
sorter: true,
|
||||
component: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,10 +42,11 @@ export function createApi() {
|
|||
params: { id }
|
||||
});
|
||||
},
|
||||
async ListAll() {
|
||||
async GetApiToken(id: number) {
|
||||
return await request({
|
||||
url: apiPrefix + "/all",
|
||||
method: "post"
|
||||
url: apiPrefix + "/getApiToken",
|
||||
method: "post",
|
||||
data: { id }
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -72,13 +72,30 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
}
|
||||
},
|
||||
rowHandle: {
|
||||
width: 200,
|
||||
width: 300,
|
||||
fixed: "right",
|
||||
buttons: {
|
||||
view: { show: true },
|
||||
copy: { show: false },
|
||||
edit: { show: false },
|
||||
remove: { show: true }
|
||||
remove: { show: true },
|
||||
gen: {
|
||||
text: "测试ApiToken",
|
||||
async click({ row }) {
|
||||
const apiToken = await api.GetApiToken(row.id);
|
||||
Modal.info({
|
||||
title: "ApiToken",
|
||||
content: () => {
|
||||
return (
|
||||
<div>
|
||||
<div>测试ApiKey如下,您可以在3分钟内使用它进行开放接口请求测试</div>
|
||||
<div>{apiToken}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
columns: {
|
||||
|
|
|
@ -19,7 +19,6 @@ import * as libServer from '@certd/lib-server';
|
|||
import * as commercial from '@certd/commercial-core';
|
||||
import * as upload from '@midwayjs/upload';
|
||||
import { setLogger } from '@certd/acme-client';
|
||||
|
||||
process.on('uncaughtException', error => {
|
||||
console.error('未捕获的异常:', error);
|
||||
// 在这里可以添加日志记录、发送错误通知等操作
|
||||
|
|
|
@ -10,6 +10,6 @@ export class BaseOpenController extends BaseController {
|
|||
const encrypted = encryptor.encrypt(data);
|
||||
return this.ok(encrypted);
|
||||
}
|
||||
super.ok(res);
|
||||
return super.ok(res);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@ import { OpenKey } from '../../../modules/open/service/open-key-service.js';
|
|||
import { BaseOpenController } from '../base-open-controller.js';
|
||||
|
||||
export type CertGetReq = {
|
||||
domains: string;
|
||||
domains?: string;
|
||||
certId: number;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -25,17 +26,13 @@ export class OpenCertController extends BaseOpenController {
|
|||
const openKey: OpenKey = this.ctx.openKey;
|
||||
const userId = openKey.userId;
|
||||
if (!userId) {
|
||||
return Constants.res.openKeyError;
|
||||
throw new CodeException(Constants.res.openKeyError);
|
||||
}
|
||||
|
||||
const domains = bean.domains || query.domains;
|
||||
if (!domains) {
|
||||
throw new CodeException(Constants.res.openParamError);
|
||||
}
|
||||
const domainArr = domains.split(',');
|
||||
const res: CertInfo = await this.certInfoService.getCertInfo({
|
||||
userId,
|
||||
domains: domainArr,
|
||||
domains: bean.domains || query.domains,
|
||||
certId: bean.certId || query.certId,
|
||||
});
|
||||
return this.ok(res);
|
||||
}
|
||||
|
|
|
@ -62,4 +62,11 @@ export class OpenKeyController extends CrudController<OpenKeyService> {
|
|||
await this.service.checkUserId(id, this.getUserId());
|
||||
return await super.delete(id);
|
||||
}
|
||||
|
||||
@Post('/getApiToken', { summary: Constants.per.authOnly })
|
||||
async getApiToken(@Query('id') id: number) {
|
||||
await this.service.checkUserId(id, this.getUserId());
|
||||
const token = await this.service.getApiToken(id);
|
||||
return this.ok(token);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,8 +88,7 @@ export class AuthorityMiddleware implements IWebMiddleware {
|
|||
|
||||
async doOpenHandler(ctx: IMidwayKoaContext, next: Next) {
|
||||
//开放接口
|
||||
let openKey = ctx.get('Authorization') || '';
|
||||
openKey = openKey.replace('Bearer ', '').trim();
|
||||
const openKey = ctx.get('x-api-token') || '';
|
||||
if (!openKey) {
|
||||
ctx.status = 401;
|
||||
ctx.body = Constants.res.auth;
|
||||
|
|
|
@ -72,10 +72,29 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
|||
});
|
||||
}
|
||||
|
||||
async getCertInfo(param: { domains: string[]; userId: number }) {
|
||||
const { domains, userId } = param;
|
||||
async getCertInfo(params: { domains?: string; certId?: number; userId: number }) {
|
||||
const { domains, certId, userId } = params;
|
||||
if (certId) {
|
||||
return await this.getCertInfoById({ id: certId, userId });
|
||||
}
|
||||
return await this.getCertInfoByDomains({
|
||||
domains,
|
||||
userId,
|
||||
});
|
||||
}
|
||||
|
||||
private async getCertInfoByDomains(params: { domains: string; userId: number }) {
|
||||
const { domains, userId } = params;
|
||||
if (!domains) {
|
||||
throw new CodeException(Constants.res.openCertNotFound);
|
||||
}
|
||||
const domainArr = domains.split(',');
|
||||
|
||||
const list = await this.find({
|
||||
select: {
|
||||
id: true,
|
||||
domains: true,
|
||||
},
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
|
@ -83,12 +102,25 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
|||
//遍历查找
|
||||
const matched = list.find(item => {
|
||||
const itemDomains = item.domains.split(',');
|
||||
return utils.domain.match(domains, itemDomains);
|
||||
return utils.domain.match(domainArr, itemDomains);
|
||||
});
|
||||
if (!matched || !matched.certInfo) {
|
||||
if (!matched) {
|
||||
throw new CodeException(Constants.res.openCertNotFound);
|
||||
}
|
||||
const certInfo = JSON.parse(matched.certInfo) as CertInfo;
|
||||
|
||||
return await this.getCertInfoById({ id: matched.id, userId: userId });
|
||||
}
|
||||
|
||||
async getCertInfoById(req: { id: number; userId: number }) {
|
||||
const entity = await this.info(req.id);
|
||||
if (!entity || entity.userId !== req.userId) {
|
||||
throw new CodeException(Constants.res.openCertNotFound);
|
||||
}
|
||||
|
||||
if (!entity.certInfo) {
|
||||
throw new CodeException(Constants.res.openCertNotReady);
|
||||
}
|
||||
const certInfo = JSON.parse(entity.certInfo) as CertInfo;
|
||||
const certReader = new CertReader(certInfo);
|
||||
return certReader.toCertInfo();
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import { Repository } from 'typeorm';
|
|||
import { OpenKeyEntity } from '../entity/open-key.js';
|
||||
import { utils } from '@certd/basic';
|
||||
import crypto from 'crypto';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
export type OpenKey = {
|
||||
userId: number;
|
||||
|
@ -85,4 +86,21 @@ export class OpenKeyService extends BaseService<OpenKeyEntity> {
|
|||
encrypt: encrypt,
|
||||
};
|
||||
}
|
||||
|
||||
async getApiToken(id: number) {
|
||||
const entity = await this.repository.findOne({ where: { id } });
|
||||
if (!entity) {
|
||||
throw new Error('id不存在');
|
||||
}
|
||||
const { keyId, keySecret } = entity;
|
||||
const openKey = {
|
||||
keyId,
|
||||
t: dayjs().unix(),
|
||||
encrypt: false,
|
||||
signType: 'md5',
|
||||
};
|
||||
const content = JSON.stringify(openKey);
|
||||
const sign = utils.hash.md5(content + keySecret);
|
||||
return Buffer.from(content).toString('base64') + '.' + sign;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue