mirror of
https://github.com/certd/certd.git
synced 2026-04-24 12:27:25 +08:00
Merge remote-tracking branch 'origin/v2-dev' into v2-dev
This commit is contained in:
@@ -40,6 +40,17 @@ export const certdResources = [
|
||||
cache: true
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "证书仓库",
|
||||
name: "CertStore",
|
||||
path: "/certd/monitor/cert",
|
||||
component: "/certd/monitor/cert/index.vue",
|
||||
meta: {
|
||||
icon: "ion:shield-checkmark-outline",
|
||||
auth: true,
|
||||
isMenu: true
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "站点证书监控",
|
||||
name: "SiteCertMonitor",
|
||||
@@ -80,21 +91,6 @@ export const certdResources = [
|
||||
auth: true
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "证书仓库",
|
||||
name: "CertStore",
|
||||
path: "/certd/monitor/cert",
|
||||
component: "/certd/monitor/cert/index.vue",
|
||||
meta: {
|
||||
show: () => {
|
||||
const settingStore = useSettingStore();
|
||||
return settingStore.isPlus;
|
||||
},
|
||||
icon: "ion:shield-checkmark-outline",
|
||||
auth: true,
|
||||
isMenu: false
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "授权管理",
|
||||
name: "AccessManager",
|
||||
@@ -106,6 +102,17 @@ export const certdResources = [
|
||||
cache: true
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "OpenKey",
|
||||
name: "OpenKey",
|
||||
path: "/certd/open/openkey",
|
||||
component: "/certd/open/openkey/index.vue",
|
||||
meta: {
|
||||
icon: "ion:disc-outline",
|
||||
auth: true,
|
||||
cache: true
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "通知设置",
|
||||
name: "NotificationManager",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { pipelineGroupApi } from "./api";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const { t } = useI18n();
|
||||
@@ -78,23 +79,23 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
show: false
|
||||
}
|
||||
},
|
||||
domain: {
|
||||
title: "主域名",
|
||||
search: {
|
||||
show: true
|
||||
},
|
||||
type: "text",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
width: 180,
|
||||
sorter: true,
|
||||
component: {
|
||||
name: "fs-values-format"
|
||||
}
|
||||
}
|
||||
},
|
||||
// domain: {
|
||||
// title: "主域名",
|
||||
// search: {
|
||||
// show: true
|
||||
// },
|
||||
// type: "text",
|
||||
// form: {
|
||||
// show: false
|
||||
// },
|
||||
// column: {
|
||||
// width: 180,
|
||||
// sorter: true,
|
||||
// component: {
|
||||
// name: "fs-values-format"
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
domains: {
|
||||
title: "全部域名",
|
||||
search: {
|
||||
@@ -105,10 +106,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
rules: [{ required: true, message: "请输入域名" }]
|
||||
},
|
||||
column: {
|
||||
width: 350,
|
||||
width: 450,
|
||||
sorter: true,
|
||||
component: {
|
||||
name: "fs-values-format"
|
||||
name: "fs-values-format",
|
||||
color: "auto"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -124,17 +126,40 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
show: false
|
||||
}
|
||||
},
|
||||
"pipeline.title": {
|
||||
title: "已关联流水线",
|
||||
search: { show: false },
|
||||
type: "link",
|
||||
expiresTime: {
|
||||
title: "过期时间",
|
||||
search: {
|
||||
show: true
|
||||
},
|
||||
type: "date",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
width: 250,
|
||||
sorter: true,
|
||||
component: {}
|
||||
cellRender({ value }) {
|
||||
if (!value) {
|
||||
return "-";
|
||||
}
|
||||
const expireDate = dayjs(value).format("YYYY-MM-DD");
|
||||
const leftDays = dayjs(value).diff(dayjs(), "day");
|
||||
const color = leftDays < 20 ? "red" : "#389e0d";
|
||||
const percent = (leftDays / 90) * 100;
|
||||
return <a-progress title={expireDate + "过期"} percent={percent} strokeColor={color} format={(percent: number) => `${leftDays}天`} />;
|
||||
}
|
||||
}
|
||||
},
|
||||
certProvider: {
|
||||
title: "证书颁发机构",
|
||||
search: {
|
||||
show: true
|
||||
},
|
||||
type: "text",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
width: 200
|
||||
}
|
||||
},
|
||||
applyTime: {
|
||||
@@ -150,42 +175,17 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
sorter: true
|
||||
}
|
||||
},
|
||||
expiresTime: {
|
||||
title: "过期时间",
|
||||
search: {
|
||||
show: true
|
||||
},
|
||||
type: "date",
|
||||
"pipeline.title": {
|
||||
title: "已关联流水线",
|
||||
search: { show: false },
|
||||
type: "link",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
sorter: true
|
||||
}
|
||||
},
|
||||
fromType: {
|
||||
title: "来源",
|
||||
search: {
|
||||
show: true
|
||||
},
|
||||
type: "text",
|
||||
form: { show: false },
|
||||
column: {
|
||||
width: 100,
|
||||
sorter: true
|
||||
}
|
||||
},
|
||||
certProvider: {
|
||||
title: "证书颁发机构",
|
||||
search: {
|
||||
show: true
|
||||
},
|
||||
type: "text",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
width: 400
|
||||
width: 350,
|
||||
sorter: true,
|
||||
component: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<template #header>
|
||||
<div class="title">
|
||||
证书仓库
|
||||
<span class="sub">管理证书,后续将支持手动上传证书并部署</span>
|
||||
<span class="sub">从流水线生成的证书,后续将支持手动上传证书并部署</span>
|
||||
</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import { request } from "/src/api/service";
|
||||
|
||||
export function createApi() {
|
||||
const apiPrefix = "/open/key";
|
||||
return {
|
||||
async GetList(query: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/page",
|
||||
method: "post",
|
||||
data: query
|
||||
});
|
||||
},
|
||||
|
||||
async AddObj(obj: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/add",
|
||||
method: "post",
|
||||
data: obj
|
||||
});
|
||||
},
|
||||
|
||||
async UpdateObj(obj: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/update",
|
||||
method: "post",
|
||||
data: obj
|
||||
});
|
||||
},
|
||||
|
||||
async DelObj(id: number) {
|
||||
return await request({
|
||||
url: apiPrefix + "/delete",
|
||||
method: "post",
|
||||
params: { id }
|
||||
});
|
||||
},
|
||||
|
||||
async GetObj(id: number) {
|
||||
return await request({
|
||||
url: apiPrefix + "/info",
|
||||
method: "post",
|
||||
params: { id }
|
||||
});
|
||||
},
|
||||
async GetApiToken(id: number) {
|
||||
return await request({
|
||||
url: apiPrefix + "/getApiToken",
|
||||
method: "post",
|
||||
data: { id }
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const pipelineGroupApi = createApi();
|
||||
@@ -0,0 +1,165 @@
|
||||
// @ts-ignore
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { pipelineGroupApi } from "./api";
|
||||
import dayjs from "dayjs";
|
||||
import { Modal } from "ant-design-vue";
|
||||
import CertView from "/@/views/certd/pipeline/cert-view.vue";
|
||||
import { useModal } from "/@/use/use-modal";
|
||||
|
||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const { t } = useI18n();
|
||||
const api = pipelineGroupApi;
|
||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||
return await api.GetList(query);
|
||||
};
|
||||
const editRequest = async (req: EditReq) => {
|
||||
const { form, row } = req;
|
||||
form.id = row.id;
|
||||
const res = await api.UpdateObj(form);
|
||||
return res;
|
||||
};
|
||||
const delRequest = async (req: DelReq) => {
|
||||
const { row } = req;
|
||||
return await api.DelObj(row.id);
|
||||
};
|
||||
|
||||
const addRequest = async (req: AddReq) => {
|
||||
const { form } = req;
|
||||
const res = await api.AddObj(form);
|
||||
return res;
|
||||
};
|
||||
const model = useModal();
|
||||
return {
|
||||
crudOptions: {
|
||||
request: {
|
||||
pageRequest,
|
||||
addRequest,
|
||||
editRequest,
|
||||
delRequest
|
||||
},
|
||||
search: {
|
||||
show: false
|
||||
},
|
||||
form: {
|
||||
labelCol: {
|
||||
//固定label宽度
|
||||
span: null,
|
||||
style: {
|
||||
width: "100px"
|
||||
}
|
||||
},
|
||||
col: {
|
||||
span: 22
|
||||
},
|
||||
wrapper: {
|
||||
width: 600
|
||||
}
|
||||
},
|
||||
actionbar: {
|
||||
buttons: {
|
||||
add: {
|
||||
text: "生成新的Key",
|
||||
click() {
|
||||
Modal.confirm({
|
||||
title: "确认",
|
||||
content: "确定要生成新的Key?",
|
||||
async onOk() {
|
||||
await api.AddObj({});
|
||||
await crudExpose.doRefresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
rowHandle: {
|
||||
width: 300,
|
||||
fixed: "right",
|
||||
buttons: {
|
||||
view: { show: true },
|
||||
copy: { show: false },
|
||||
edit: { show: false },
|
||||
remove: { show: true },
|
||||
gen: {
|
||||
text: "测试ApiToken",
|
||||
async click({ row }) {
|
||||
const apiToken = await api.GetApiToken(row.id);
|
||||
|
||||
model.success({
|
||||
title: "ApiToken",
|
||||
maskClosable: true,
|
||||
okText: "确定",
|
||||
width: 600,
|
||||
content: () => {
|
||||
return (
|
||||
<div>
|
||||
<div class={"m-10 p-10"}>测试ApiKey如下,您可以在3分钟内使用它进行开放接口请求测试</div>
|
||||
<div class={"m-10 p-10"} style={{ border: "1px solid #333" }}>
|
||||
<fs-copyable model-value={apiToken}></fs-copyable>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
columns: {
|
||||
id: {
|
||||
title: "ID",
|
||||
key: "id",
|
||||
type: "number",
|
||||
search: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
width: 100,
|
||||
editable: {
|
||||
disabled: true
|
||||
}
|
||||
},
|
||||
form: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
keyId: {
|
||||
title: "KeyId",
|
||||
search: {
|
||||
show: false
|
||||
},
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
type: "text",
|
||||
column: {
|
||||
width: 200,
|
||||
sorter: true
|
||||
}
|
||||
},
|
||||
keySecret: {
|
||||
title: "KeySecret",
|
||||
type: "text",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
width: 550,
|
||||
sorter: true
|
||||
}
|
||||
},
|
||||
createTime: {
|
||||
title: "创建时间",
|
||||
type: "datetime",
|
||||
search: {
|
||||
show: false
|
||||
},
|
||||
form: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<fs-page>
|
||||
<template #header>
|
||||
<div class="title">开放接口密钥管理</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineComponent, onActivated, onMounted } from "vue";
|
||||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import createCrudOptions from "./crud";
|
||||
import { createApi } from "./api";
|
||||
defineOptions({
|
||||
name: "OpenKey"
|
||||
});
|
||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
|
||||
|
||||
// 页面打开后获取列表数据
|
||||
onMounted(() => {
|
||||
crudExpose.doRefresh();
|
||||
});
|
||||
onActivated(() => {
|
||||
crudExpose.doRefresh();
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE "cd_open_key"
|
||||
(
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"user_id" integer,
|
||||
"key_id" varchar(50),
|
||||
"key_secret" varchar(100),
|
||||
"disabled" boolean NOT NULL DEFAULT (false),
|
||||
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE INDEX "index_open_key_user_id" ON "cd_open_key" ("user_id");
|
||||
CREATE INDEX "index_open_key_key_id" ON "cd_open_key" ("key_id");
|
||||
@@ -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);
|
||||
// 在这里可以添加日志记录、发送错误通知等操作
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { BaseController, Encryptor } from '@certd/lib-server';
|
||||
import { OpenKey } from '../../modules/open/service/open-key-service.js';
|
||||
|
||||
export class BaseOpenController extends BaseController {
|
||||
ok(res: any) {
|
||||
const openKey: OpenKey = this.ctx.openKey;
|
||||
if (openKey.encrypt) {
|
||||
const data = JSON.stringify(res);
|
||||
const encryptor = new Encryptor(openKey.keySecret, 'hex');
|
||||
const encrypted = encryptor.encrypt(data);
|
||||
return this.ok(encrypted);
|
||||
}
|
||||
return super.ok(res);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { CodeException, Constants, EncryptService } from '@certd/lib-server';
|
||||
import { CertInfoService } from '../../../modules/monitor/service/cert-info-service.js';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { OpenKey } from '../../../modules/open/service/open-key-service.js';
|
||||
import { BaseOpenController } from '../base-open-controller.js';
|
||||
|
||||
export type CertGetReq = {
|
||||
domains?: string;
|
||||
certId: number;
|
||||
};
|
||||
|
||||
/**
|
||||
*/
|
||||
@Provide()
|
||||
@Controller('/api/v1/cert')
|
||||
export class OpenCertController extends BaseOpenController {
|
||||
@Inject()
|
||||
certInfoService: CertInfoService;
|
||||
@Inject()
|
||||
encryptService: EncryptService;
|
||||
|
||||
@Get('/get', { summary: Constants.per.open })
|
||||
@Post('/get', { summary: Constants.per.open })
|
||||
async get(@Body(ALL) bean: CertGetReq, @Query(ALL) query: CertGetReq) {
|
||||
const openKey: OpenKey = this.ctx.openKey;
|
||||
const userId = openKey.userId;
|
||||
if (!userId) {
|
||||
throw new CodeException(Constants.res.openKeyError);
|
||||
}
|
||||
|
||||
const res: CertInfo = await this.certInfoService.getCertInfo({
|
||||
userId,
|
||||
domains: bean.domains || query.domains,
|
||||
certId: bean.certId || query.certId,
|
||||
});
|
||||
return this.ok(res);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { AccessService, Constants } from '@certd/lib-server';
|
||||
import { AccessController } from '../../pipeline/access-controller.js';
|
||||
import { AccessController } from '../../user/pipeline/access-controller.js';
|
||||
import { checkComm } from '@certd/plus-core';
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import { Rule, RuleType } from '@midwayjs/validate';
|
||||
import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { BaseController, Constants } from '@certd/lib-server';
|
||||
import { CodeService } from '../../modules/basic/service/code-service.js';
|
||||
import { EmailService } from '../../modules/basic/service/email-service.js';
|
||||
import { CodeService } from '../../../modules/basic/service/code-service.js';
|
||||
import { EmailService } from '../../../modules/basic/service/email-service.js';
|
||||
|
||||
export class SmsCodeReq {
|
||||
@Rule(RuleType.string().required())
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
||||
import { BaseController } from '@certd/lib-server';
|
||||
import { EmailService } from '../../modules/basic/service/email-service.js';
|
||||
import { EmailService } from '../../../modules/basic/service/email-service.js';
|
||||
import { Constants } from '@certd/lib-server';
|
||||
|
||||
/**
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
||||
import { BaseController, Constants } from '@certd/lib-server';
|
||||
import { CnameRecordService } from '../../modules/cname/service/cname-record-service.js';
|
||||
import { CnameProviderService } from '../../modules/cname/service/cname-provider-service.js';
|
||||
import { CnameRecordService } from '../../../modules/cname/service/cname-record-service.js';
|
||||
import { CnameProviderService } from '../../../modules/cname/service/cname-provider-service.js';
|
||||
|
||||
/**
|
||||
* 授权
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { Constants, CrudController } from '@certd/lib-server';
|
||||
import { CnameRecordService } from '../../modules/cname/service/cname-record-service.js';
|
||||
import { CnameRecordService } from '../../../modules/cname/service/cname-record-service.js';
|
||||
|
||||
/**
|
||||
* 授权
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
import { Controller, Inject, Post, Provide } from '@midwayjs/core';
|
||||
import { BaseController, Constants } from '@certd/lib-server';
|
||||
import { UserService } from '../../modules/sys/authority/service/user-service.js';
|
||||
import { RoleService } from '../../modules/sys/authority/service/role-service.js';
|
||||
import { PipelineService } from '../../modules/pipeline/service/pipeline-service.js';
|
||||
import { HistoryService } from '../../modules/pipeline/service/history-service.js';
|
||||
import { UserService } from '../../../modules/sys/authority/service/user-service.js';
|
||||
import { RoleService } from '../../../modules/sys/authority/service/role-service.js';
|
||||
import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js';
|
||||
import { HistoryService } from '../../../modules/pipeline/service/history-service.js';
|
||||
|
||||
export type ChartItem = {
|
||||
name: string;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
||||
import { LoginService } from '../../modules/login/service/login-service.js';
|
||||
import { LoginService } from '../../../modules/login/service/login-service.js';
|
||||
import { BaseController, Constants, SysPublicSettings, SysSettingsService } from '@certd/lib-server';
|
||||
import { CodeService } from '../../modules/basic/service/code-service.js';
|
||||
import { CodeService } from '../../../modules/basic/service/code-service.js';
|
||||
import { checkComm } from '@certd/plus-core';
|
||||
|
||||
/**
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
||||
import { BaseController, Constants, SysSettingsService } from '@certd/lib-server';
|
||||
import { RegisterType, UserService } from '../../modules/sys/authority/service/user-service.js';
|
||||
import { CodeService } from '../../modules/basic/service/code-service.js';
|
||||
import { RegisterType, UserService } from '../../../modules/sys/authority/service/user-service.js';
|
||||
import { CodeService } from '../../../modules/basic/service/code-service.js';
|
||||
import { checkComm, checkPlus } from '@certd/plus-core';
|
||||
|
||||
export type RegisterReq = {
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
||||
import { BaseController, Constants } from '@certd/lib-server';
|
||||
import { UserService } from '../../modules/sys/authority/service/user-service.js';
|
||||
import { RoleService } from '../../modules/sys/authority/service/role-service.js';
|
||||
import { UserService } from '../../../modules/sys/authority/service/user-service.js';
|
||||
import { RoleService } from '../../../modules/sys/authority/service/role-service.js';
|
||||
|
||||
/**
|
||||
*/
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { CrudController } from '@certd/lib-server';
|
||||
import { Constants } from '@certd/lib-server';
|
||||
import { UserSettingsService } from '../../modules/mine/service/user-settings-service.js';
|
||||
import { UserSettingsEntity } from '../../modules/mine/entity/user-settings.js';
|
||||
import { UserSettingsService } from '../../../modules/mine/service/user-settings-service.js';
|
||||
import { UserSettingsEntity } from '../../../modules/mine/entity/user-settings.js';
|
||||
|
||||
/**
|
||||
*/
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { Constants, CrudController } from '@certd/lib-server';
|
||||
import { AuthService } from '../../modules/sys/authority/service/auth-service.js';
|
||||
import { CertInfoService } from '../../modules/monitor/index.js';
|
||||
import { PipelineService } from '../../modules/pipeline/service/pipeline-service.js';
|
||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||
import { CertInfoService } from '../../../modules/monitor/index.js';
|
||||
import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js';
|
||||
|
||||
/**
|
||||
*/
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { Constants, CrudController } from '@certd/lib-server';
|
||||
import { AuthService } from '../../modules/sys/authority/service/auth-service.js';
|
||||
import { SiteInfoService } from '../../modules/monitor/index.js';
|
||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||
import { SiteInfoService } from '../../../modules/monitor/service/site-info-service.js';
|
||||
|
||||
/**
|
||||
*/
|
||||
@@ -0,0 +1,72 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { Constants, CrudController } from '@certd/lib-server';
|
||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||
import { OpenKeyService } from '../../../modules/open/service/open-key-service.js';
|
||||
|
||||
/**
|
||||
*/
|
||||
@Provide()
|
||||
@Controller('/api/open/key')
|
||||
export class OpenKeyController extends CrudController<OpenKeyService> {
|
||||
@Inject()
|
||||
service: OpenKeyService;
|
||||
@Inject()
|
||||
authService: AuthService;
|
||||
|
||||
getService(): OpenKeyService {
|
||||
return this.service;
|
||||
}
|
||||
|
||||
@Post('/page', { summary: Constants.per.authOnly })
|
||||
async page(@Body(ALL) body: any) {
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
const res = await this.service.page({
|
||||
query: body.query,
|
||||
page: body.page,
|
||||
sort: body.sort,
|
||||
});
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body: any) {
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.getUserId();
|
||||
return await super.list(body);
|
||||
}
|
||||
|
||||
@Post('/add', { summary: Constants.per.authOnly })
|
||||
async add() {
|
||||
const bean: any = {};
|
||||
bean.userId = this.getUserId();
|
||||
const res = await this.service.add(bean);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/update', { summary: Constants.per.authOnly })
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.service.checkUserId(bean.id, this.getUserId());
|
||||
delete bean.userId;
|
||||
await this.service.update(bean);
|
||||
return this.ok();
|
||||
}
|
||||
@Post('/info', { summary: Constants.per.authOnly })
|
||||
async info(@Query('id') id: number) {
|
||||
await this.service.checkUserId(id, this.getUserId());
|
||||
return await super.info(id);
|
||||
}
|
||||
|
||||
@Post('/delete', { summary: Constants.per.authOnly })
|
||||
async delete(@Query('id') id: number) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { Constants, CrudController } from '@certd/lib-server';
|
||||
import { AccessService } from '@certd/lib-server';
|
||||
import { AuthService } from '../../modules/sys/authority/service/auth-service.js';
|
||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||
import { AccessDefine } from '@certd/pipeline';
|
||||
|
||||
/**
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { PipelineService } from '../../modules/pipeline/service/pipeline-service.js';
|
||||
import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js';
|
||||
import { BaseController, Constants } from '@certd/lib-server';
|
||||
import { StorageService } from '../../modules/pipeline/service/storage-service.js';
|
||||
import { StorageService } from '../../../modules/pipeline/service/storage-service.js';
|
||||
|
||||
@Provide()
|
||||
@Controller('/api/pi/cert')
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { ALL, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { DnsProviderService } from '../../modules/pipeline/service/dns-provider-service.js';
|
||||
import { DnsProviderService } from '../../../modules/pipeline/service/dns-provider-service.js';
|
||||
import { BaseController } from '@certd/lib-server';
|
||||
import { Constants } from '@certd/lib-server';
|
||||
|
||||
+2
-2
@@ -11,9 +11,9 @@ import {
|
||||
TaskInstanceContext,
|
||||
} from '@certd/pipeline';
|
||||
import { AccessService, AccessGetter } from '@certd/lib-server';
|
||||
import { EmailService } from '../../modules/basic/service/email-service.js';
|
||||
import { EmailService } from '../../../modules/basic/service/email-service.js';
|
||||
import { http, HttpRequestConfig, logger, mergeUtils, utils } from '@certd/basic';
|
||||
import { NotificationService } from '../../modules/pipeline/service/notification-service.js';
|
||||
import { NotificationService } from '../../../modules/pipeline/service/notification-service.js';
|
||||
|
||||
@Provide()
|
||||
@Controller('/api/pi/handle')
|
||||
+7
-7
@@ -1,14 +1,14 @@
|
||||
import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { CommonException, Constants, CrudController, PermissionException } from '@certd/lib-server';
|
||||
import { PipelineEntity } from '../../modules/pipeline/entity/pipeline.js';
|
||||
import { HistoryService } from '../../modules/pipeline/service/history-service.js';
|
||||
import { HistoryLogService } from '../../modules/pipeline/service/history-log-service.js';
|
||||
import { HistoryEntity } from '../../modules/pipeline/entity/history.js';
|
||||
import { HistoryLogEntity } from '../../modules/pipeline/entity/history-log.js';
|
||||
import { PipelineService } from '../../modules/pipeline/service/pipeline-service.js';
|
||||
import { PipelineEntity } from '../../../modules/pipeline/entity/pipeline.js';
|
||||
import { HistoryService } from '../../../modules/pipeline/service/history-service.js';
|
||||
import { HistoryLogService } from '../../../modules/pipeline/service/history-log-service.js';
|
||||
import { HistoryEntity } from '../../../modules/pipeline/entity/history.js';
|
||||
import { HistoryLogEntity } from '../../../modules/pipeline/entity/history-log.js';
|
||||
import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js';
|
||||
import * as fs from 'fs';
|
||||
import { logger } from '@certd/basic';
|
||||
import { AuthService } from '../../modules/sys/authority/service/auth-service.js';
|
||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||
import { SysSettingsService } from '@certd/lib-server';
|
||||
import { In } from 'typeorm';
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { Constants, CrudController, ValidateException } from '@certd/lib-server';
|
||||
import { NotificationService } from '../../modules/pipeline/service/notification-service.js';
|
||||
import { AuthService } from '../../modules/sys/authority/service/auth-service.js';
|
||||
import { NotificationService } from '../../../modules/pipeline/service/notification-service.js';
|
||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||
import { NotificationDefine } from '@certd/pipeline';
|
||||
import { checkPlus } from '@certd/plus-core';
|
||||
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { Constants, CrudController, SysSettingsService } from '@certd/lib-server';
|
||||
import { PipelineService } from '../../modules/pipeline/service/pipeline-service.js';
|
||||
import { PipelineEntity } from '../../modules/pipeline/entity/pipeline.js';
|
||||
import { HistoryService } from '../../modules/pipeline/service/history-service.js';
|
||||
import { AuthService } from '../../modules/sys/authority/service/auth-service.js';
|
||||
import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js';
|
||||
import { PipelineEntity } from '../../../modules/pipeline/entity/pipeline.js';
|
||||
import { HistoryService } from '../../../modules/pipeline/service/history-service.js';
|
||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||
|
||||
/**
|
||||
* 证书
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { Constants, CrudController } from '@certd/lib-server';
|
||||
import { AuthService } from '../../modules/sys/authority/service/auth-service.js';
|
||||
import { PipelineGroupService } from '../../modules/pipeline/service/pipeline-group-service.js';
|
||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||
import { PipelineGroupService } from '../../../modules/pipeline/service/pipeline-group-service.js';
|
||||
|
||||
/**
|
||||
* 通知
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { BaseController, Constants } from '@certd/lib-server';
|
||||
import { PluginService } from '../../modules/plugin/service/plugin-service.js';
|
||||
import { PluginConfigService } from '../../modules/plugin/service/plugin-config-service.js';
|
||||
import { PluginService } from '../../../modules/plugin/service/plugin-service.js';
|
||||
import { PluginConfigService } from '../../../modules/plugin/service/plugin-config-service.js';
|
||||
|
||||
/**
|
||||
* 插件
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Init, Inject, MidwayWebRouterService, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { IMidwayKoaContext, IWebMiddleware, NextFunction } from '@midwayjs/koa';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { Constants } from '@certd/lib-server';
|
||||
import { Constants, SysPrivateSettings, SysSettingsService } from '@certd/lib-server';
|
||||
import { logger } from '@certd/basic';
|
||||
import { AuthService } from '../modules/sys/authority/service/auth-service.js';
|
||||
import { SysSettingsService } from '@certd/lib-server';
|
||||
import { SysPrivateSettings } from '@certd/lib-server';
|
||||
import { Next } from 'koa';
|
||||
import { OpenKeyService } from '../modules/open/service/open-key-service.js';
|
||||
|
||||
/**
|
||||
* 权限校验
|
||||
@@ -18,6 +18,8 @@ export class AuthorityMiddleware implements IWebMiddleware {
|
||||
@Inject()
|
||||
authService: AuthService;
|
||||
@Inject()
|
||||
openKeyService: OpenKeyService;
|
||||
@Inject()
|
||||
sysSettingsService: SysSettingsService;
|
||||
|
||||
secret: string;
|
||||
@@ -48,6 +50,10 @@ export class AuthorityMiddleware implements IWebMiddleware {
|
||||
return;
|
||||
}
|
||||
|
||||
if (permission === Constants.per.open) {
|
||||
return this.doOpenHandler(ctx, next);
|
||||
}
|
||||
|
||||
let token = ctx.get('Authorization') || '';
|
||||
token = token.replace('Bearer ', '').trim();
|
||||
if (!token) {
|
||||
@@ -79,4 +85,20 @@ export class AuthorityMiddleware implements IWebMiddleware {
|
||||
await next();
|
||||
};
|
||||
}
|
||||
|
||||
async doOpenHandler(ctx: IMidwayKoaContext, next: Next) {
|
||||
//开放接口
|
||||
const openKey = ctx.get('x-api-token') || '';
|
||||
if (!openKey) {
|
||||
ctx.status = 401;
|
||||
ctx.body = Constants.res.auth;
|
||||
return;
|
||||
}
|
||||
|
||||
//校验 openKey
|
||||
const openKeyRes = await this.openKeyService.verifyOpenKey(openKey);
|
||||
ctx.user = { id: openKeyRes.userId };
|
||||
ctx.openKey = openKeyRes;
|
||||
await next();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Autoload, Init, Inject, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { CertInfoService } from '../monitor/index.js';
|
||||
import { pipelineEmitter } from '@certd/pipeline';
|
||||
import { CertReader, EVENT_CERT_APPLY_SUCCESS } from '@certd/plugin-cert';
|
||||
import { PipelineEvent } from '@certd/pipeline/dist/service/emit.js';
|
||||
|
||||
@Autoload()
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
export class AutoEPipelineEmitterRegister {
|
||||
@Inject()
|
||||
certInfoService: CertInfoService;
|
||||
|
||||
@Init()
|
||||
async init() {
|
||||
await this.onCertApplySuccess();
|
||||
}
|
||||
async onCertApplySuccess() {
|
||||
pipelineEmitter.on(EVENT_CERT_APPLY_SUCCESS, async (event: PipelineEvent<CertReader>) => {
|
||||
await this.certInfoService.updateCert(event.pipeline.id, event.event);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Inject, Provide } from '@midwayjs/core';
|
||||
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { cache, isDev, randomNumber } from '@certd/basic';
|
||||
import { SysSettingsService, SysSiteInfo } from '@certd/lib-server';
|
||||
import { SmsServiceFactory } from '../sms/factory.js';
|
||||
@@ -13,6 +13,7 @@ import { isComm } from '@certd/plus-core';
|
||||
/**
|
||||
*/
|
||||
@Provide()
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
export class CodeService {
|
||||
@Inject()
|
||||
sysSettingsService: SysSettingsService;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Config, Inject, Provide } from '@midwayjs/core';
|
||||
import { Config, Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { UserService } from '../../sys/authority/service/user-service.js';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { CommonException } from '@certd/lib-server';
|
||||
@@ -14,6 +14,7 @@ import { CodeService } from '../../basic/service/code-service.js';
|
||||
* 系统用户
|
||||
*/
|
||||
@Provide()
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
export class LoginService {
|
||||
@Inject()
|
||||
userService: UserService;
|
||||
|
||||
@@ -22,7 +22,7 @@ export class CertInfoEntity {
|
||||
pipelineId: number;
|
||||
|
||||
@Column({ name: 'apply_time', comment: '申请时间' })
|
||||
applyTime: string;
|
||||
applyTime: number;
|
||||
|
||||
@Column({ name: 'from_type', comment: '来源' })
|
||||
fromType: string;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export * from "./entity/site-info.js";
|
||||
export * from "./entity/cert-info.js";
|
||||
export * from './entity/site-info.js';
|
||||
export * from './entity/cert-info.js';
|
||||
|
||||
export * from "./service/cert-info-service.js";
|
||||
export * from "./service/site-info-service.js";
|
||||
export * from './service/cert-info-service.js';
|
||||
export * from './service/site-info-service.js';
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Provide } from '@midwayjs/core';
|
||||
import { BaseService, PageReq } from '@certd/lib-server';
|
||||
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { BaseService, CodeException, Constants, PageReq } from '@certd/lib-server';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { CertInfoEntity } from '../entity/cert-info.js';
|
||||
import { utils } from '@certd/basic';
|
||||
import { CertInfo, CertReader } from '@certd/plugin-cert';
|
||||
|
||||
@Provide()
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
@InjectEntityModel(CertInfoEntity)
|
||||
repository: Repository<CertInfoEntity>;
|
||||
@@ -68,4 +71,81 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
|
||||
pipelineId: id,
|
||||
});
|
||||
}
|
||||
|
||||
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,
|
||||
},
|
||||
});
|
||||
//遍历查找
|
||||
const matched = list.find(item => {
|
||||
const itemDomains = item.domains.split(',');
|
||||
return utils.domain.match(domainArr, itemDomains);
|
||||
});
|
||||
if (!matched) {
|
||||
throw new CodeException(Constants.res.openCertNotFound);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
async updateCert(pipelineId: number, certReader: CertReader) {
|
||||
const found = await this.repository.findOne({
|
||||
where: {
|
||||
pipelineId,
|
||||
},
|
||||
});
|
||||
if (!found) {
|
||||
return;
|
||||
}
|
||||
const bean = new CertInfoEntity();
|
||||
bean.id = found.id;
|
||||
const certInfo = certReader.toCertInfo();
|
||||
bean.certInfo = JSON.stringify(certInfo);
|
||||
bean.applyTime = new Date().getTime();
|
||||
const domains = certReader.detail.domains.altNames;
|
||||
bean.domains = domains.join(',');
|
||||
bean.domain = domains[0];
|
||||
bean.domainCount = domains.length;
|
||||
bean.expiresTime = certReader.expires;
|
||||
bean.certProvider = certReader.detail.issuer.commonName;
|
||||
|
||||
await this.addOrUpdate(bean);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Inject, Provide } from '@midwayjs/core';
|
||||
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { BaseService, NeedSuiteException, NeedVIPException, SysSettingsService } from '@certd/lib-server';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
@@ -12,6 +12,7 @@ import { isComm, isPlus } from '@certd/plus-core';
|
||||
import { UserSuiteService } from '@certd/commercial-core';
|
||||
|
||||
@Provide()
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
@InjectEntityModel(SiteInfoEntity)
|
||||
repository: Repository<SiteInfoEntity>;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
@Entity('cd_open_key')
|
||||
export class OpenKeyEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column({ name: 'user_id', comment: '用户id' })
|
||||
userId: number;
|
||||
|
||||
@Column({ name: 'key_id', comment: 'keyId' })
|
||||
keyId: string;
|
||||
|
||||
@Column({ name: 'key_secret', comment: 'keySecret' })
|
||||
keySecret: string;
|
||||
|
||||
@Column({ name: 'create_time', comment: '创建时间', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createTime: Date;
|
||||
|
||||
@Column({ name: 'update_time', comment: '修改时间', default: () => 'CURRENT_TIMESTAMP' })
|
||||
updateTime: Date;
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { BaseService, Constants, CodeException, PageReq } from '@certd/lib-server';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
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;
|
||||
keyId: string;
|
||||
keySecret: string;
|
||||
encrypt: boolean;
|
||||
};
|
||||
@Provide()
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
export class OpenKeyService extends BaseService<OpenKeyEntity> {
|
||||
@InjectEntityModel(OpenKeyEntity)
|
||||
repository: Repository<OpenKeyEntity>;
|
||||
|
||||
//@ts-ignore
|
||||
getRepository() {
|
||||
return this.repository;
|
||||
}
|
||||
|
||||
async page(pageReq: PageReq<OpenKeyEntity>) {
|
||||
return await super.page(pageReq);
|
||||
}
|
||||
|
||||
async add(bean: OpenKeyEntity) {
|
||||
return await this.generate(bean.userId);
|
||||
}
|
||||
|
||||
async generate(userId: number) {
|
||||
const keyId = utils.id.simpleNanoId(18) + '_key';
|
||||
const secretKey = crypto.randomBytes(32);
|
||||
const keySecret = Buffer.from(secretKey).toString('hex');
|
||||
const entity = new OpenKeyEntity();
|
||||
entity.userId = userId;
|
||||
entity.keyId = keyId;
|
||||
entity.keySecret = keySecret;
|
||||
await this.repository.save(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
async getByKeyId(keyId: string) {
|
||||
return this.repository.findOne({ where: { keyId } });
|
||||
}
|
||||
|
||||
async verifyOpenKey(openKey: string): Promise<OpenKey> {
|
||||
// openkey 组成,content = base64({keyId,t,encrypt,signType}) ,sign = md5({keyId,t,encrypt,signType}secret) , key = content.sign
|
||||
const [content, sign] = openKey.split('.');
|
||||
const contentJson = Buffer.from(content, 'base64').toString();
|
||||
const { keyId, t, encrypt, signType } = JSON.parse(contentJson);
|
||||
// 正负不超过3分钟 ,timestamps单位为秒
|
||||
if (Math.abs(Number(t) - Math.floor(Date.now() / 1000)) > 180) {
|
||||
throw new CodeException(Constants.res.openKeyExpiresError);
|
||||
}
|
||||
|
||||
const entity = await this.getByKeyId(keyId);
|
||||
if (!entity) {
|
||||
throw new Error('openKey不存在');
|
||||
}
|
||||
const secret = entity.keySecret;
|
||||
let computedSign = '';
|
||||
if (signType === 'md5') {
|
||||
computedSign = utils.hash.md5(contentJson + secret);
|
||||
} else if (signType === 'sha256') {
|
||||
computedSign = utils.hash.sha256(contentJson + secret);
|
||||
} else {
|
||||
throw new CodeException(Constants.res.openKeySignTypeError);
|
||||
}
|
||||
if (Buffer.from(computedSign).toString('base64') !== sign) {
|
||||
throw new CodeException(Constants.res.openKeySignError);
|
||||
}
|
||||
|
||||
if (!entity.userId) {
|
||||
throw new CodeException(Constants.res.openKeyError);
|
||||
}
|
||||
|
||||
return {
|
||||
userId: entity.userId,
|
||||
keyId: entity.keyId,
|
||||
keySecret: entity.keySecret,
|
||||
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') + '.' + Buffer.from(sign).toString('base64');
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { CertInfo, CertReader } from '@certd/plugin-cert';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { DogeClient } from '../../lib/index.js';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
@@ -68,11 +68,10 @@ export class DogeCloudDeployToCDNPlugin extends AbstractTaskPlugin {
|
||||
}
|
||||
|
||||
async updateCert() {
|
||||
const certReader = new CertReader(this.cert);
|
||||
const data = await this.dogeClient.request('/cdn/cert/upload.json', {
|
||||
note: 'certd-' + dayjs().format('YYYYMMDDHHmmss'),
|
||||
cert: certReader.crt,
|
||||
private: certReader.key,
|
||||
cert: this.cert.crt,
|
||||
private: this.cert.key,
|
||||
});
|
||||
return data.id;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user