mirror of
https://github.com/certd/certd.git
synced 2026-04-04 23:10:56 +08:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f548fe7011 | ||
|
|
17a9beb514 | ||
|
|
8d42273665 | ||
|
|
251e450fab | ||
|
|
d3ba3254f1 | ||
|
|
196f9c5fa8 | ||
|
|
d00f7ee010 | ||
|
|
345571cdff | ||
|
|
1bdf7cf439 | ||
|
|
9c253e8c49 | ||
|
|
1c0b040eb0 | ||
|
|
939b8d4aa9 | ||
|
|
eec9e2e742 | ||
|
|
62f5b18022 | ||
|
|
a7ecda9b36 | ||
|
|
aec753a3f8 | ||
|
|
9225eeee44 | ||
|
|
d5608c6dab | ||
|
|
d668032310 | ||
|
|
f46db508c7 | ||
|
|
bf024bdda8 | ||
|
|
7532a96085 | ||
|
|
8e32156aa0 | ||
|
|
75ccae3f6b | ||
|
|
8d493b7a89 | ||
|
|
c6412674fa | ||
|
|
feb3fc6eb5 | ||
|
|
0874c03882 | ||
|
|
15f44e64f7 | ||
|
|
51f29d6093 | ||
|
|
7ee9d915fb | ||
|
|
d91026dc4f | ||
|
|
df88a936a5 | ||
|
|
1939c214cf |
21
CHANGELOG.md
21
CHANGELOG.md
@@ -3,6 +3,27 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.25.8](https://github.com/certd/certd/compare/v1.25.7...v1.25.8) (2024-09-30)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复pfxPassword无效的bug ([251e450](https://github.com/certd/certd/commit/251e450fabfe62405bac13e39f2153736c081ef0))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 群晖获取deviceid优化 ([8d42273](https://github.com/certd/certd/commit/8d4227366548eb70f6bc04303829e6933168f906))
|
||||
|
||||
## [1.25.7](https://github.com/certd/certd/compare/v1.25.6...v1.25.7) (2024-09-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复某些地区被屏蔽无法激活专业版的bug ([7532a96](https://github.com/certd/certd/commit/7532a960851b84d4f2cc3dba02353c5235e1a364))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 上传到主机,支持socks代理 ([d91026d](https://github.com/certd/certd/commit/d91026dc4fbfe5fedc4ee8e43dc0d08f1cf88356))
|
||||
* 支持上传到七牛云oss ([bf024bd](https://github.com/certd/certd/commit/bf024bdda8bc2a463475be5761acf0da7317a08a))
|
||||
|
||||
## [1.25.6](https://github.com/certd/certd/compare/v1.25.5...v1.25.6) (2024-09-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# Certd Open Source License
|
||||
|
||||
Certd Open Source License
|
||||
|
||||
|
||||
- This project is licensed under the **GNU Affero General Public License (AGPL)** with the following additional terms.
|
||||
- 本项目遵循 GNU Affero General Public License(AGPL),并附加以下条款。
|
||||
|
||||
48
README.md
48
README.md
@@ -5,22 +5,6 @@ Certd 是一个免费全自动申请和自动部署更新SSL证书的工具。
|
||||
|
||||
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签
|
||||
|
||||
************************
|
||||
支持开源,为爱发电,我已入驻爱发电
|
||||
https://afdian.com/a/greper
|
||||
|
||||
发电权益:
|
||||
1. 可加入发电专属群,可以获得作者一对一技术支持
|
||||
2. 您的需求我们将优先实现,并且将作为专业版功能提供
|
||||
3. 一年期专业版激活码
|
||||
4. 赠送国外免费服务器部署方案(0成本使用Certd,可能需要翻墙,不过现在性能越来越差了)
|
||||
|
||||
专业版特权
|
||||
1. 证书流水线条数无限制(免费版限制10条)
|
||||
2. 免配置发邮件功能
|
||||
3. FTP上传、cdnfly、宝塔等部署插件
|
||||
4. 更多功能增加中...
|
||||
************************
|
||||
|
||||
## 一、特性
|
||||
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
||||
@@ -45,11 +29,11 @@ https://certd.handsfree.work/
|
||||
## 三、使用教程
|
||||
本案例演示,如何配置自动申请证书,并部署到阿里云CDN,然后快要到期前自动更新证书并重新部署
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
|
||||
-------> [点我查看详细使用步骤演示](./step.md) <--------
|
||||
@@ -138,8 +122,10 @@ http://your_server_ip:7001
|
||||
# 克隆代码
|
||||
git clone https://github.com/certd/certd
|
||||
cd certd
|
||||
# 启动服务
|
||||
./start.sh
|
||||
```
|
||||
如果是windows,请先安装`git for windows` ,然后右键,选择`open git bash here`打开终端,再执行`./start.sh`命令
|
||||
|
||||
|
||||
## 五、 升级
|
||||
@@ -220,16 +206,28 @@ docker compose up -d
|
||||
</p>
|
||||
|
||||
## 十、捐赠
|
||||
************************
|
||||
支持开源,为爱发电,我已入驻爱发电
|
||||
https://afdian.com/a/greper
|
||||
|
||||
发电权益:
|
||||
1. 可加入发电专属群(先加我好友,发送发电截图,我拉你进群)
|
||||
2. 你的需求优先实现
|
||||
3. 可以获得作者一对一技术支持
|
||||
4. 更多权益陆续增加中...
|
||||
1. 可加入发电专属群,可以获得作者一对一技术支持
|
||||
2. 您的需求我们将优先实现,并且将作为专业版功能提供
|
||||
3. 一年期专业版激活码
|
||||
4. 赠送国外免费服务器部署方案(0成本使用Certd,可能需要翻墙,不过现在性能越来越差了)
|
||||
|
||||
|
||||
专业版特权对比
|
||||
|
||||
| 功能 | 免费版 | 专业版 |
|
||||
|---------|------------------------|-----------------------|
|
||||
| 免费证书申请 | 免费无限制 | 免费无限制 |
|
||||
| 自动部署插件 | 阿里云CDN、腾讯云、七牛CDN、主机部署等 | 支持群晖、宝塔、1Panel等,持续开发中 |
|
||||
| 发邮件功能 | 需要配置 | 免配置 |
|
||||
| 证书流水线条数 | 10条 | 无限制 |
|
||||
|
||||
************************
|
||||
|
||||
## 十一、贡献代码
|
||||
|
||||
1. 本地开发 [贡献插件教程](./doc/dev/development.md)
|
||||
|
||||
@@ -1 +1 @@
|
||||
14:27
|
||||
02:35
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.25.6"
|
||||
"version": "1.25.8"
|
||||
}
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
"scripts": {
|
||||
"start": "lerna bootstrap --hoist",
|
||||
"i-all": "lerna link && lerna exec npm install ",
|
||||
"publish": "npm run prepublishOnly2 && lerna publish --conventional-commits --create-release github && npm run afterpublishOnly",
|
||||
"publish": "npm run prepublishOnly2 && lerna publish --force-publish=pro/plus-core --conventional-commits --create-release github && npm run afterpublishOnly && npm run commitAll",
|
||||
"afterpublishOnly": "time /t >build.trigger && git add ./build.trigger && git commit -m \"build: trigger build image\" && TIMEOUT /T 10 && git push",
|
||||
"commitAll" : "git add . && git commit -m \"build: publish\" && git push",
|
||||
"prepublishOnly1": "npm run check && lerna run build ",
|
||||
"prepublishOnly2": "npm run check && npm run before-build && lerna run build ",
|
||||
"before-build": "cd ./packages/pro/plus-core && time /t >build.md && git add ./build.md && git commit -m \"build: prepare to build\"",
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.25.8](https://github.com/publishlab/node-acme-client/compare/v1.25.7...v1.25.8) (2024-09-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.25.7](https://github.com/publishlab/node-acme-client/compare/v1.25.6...v1.25.7) (2024-09-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.25.6](https://github.com/publishlab/node-acme-client/compare/v1.25.5...v1.25.6) (2024-09-29)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Simple and unopinionated ACME client",
|
||||
"private": false,
|
||||
"author": "nmorsman",
|
||||
"version": "1.25.6",
|
||||
"version": "1.25.8",
|
||||
"main": "src/index.js",
|
||||
"types": "types/index.d.ts",
|
||||
"license": "MIT",
|
||||
@@ -59,5 +59,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "be13390b3a9177c9d99f1efabfc285d0c377b013"
|
||||
"gitHead": "a7ecda9b36e318d169fe1a198fee8455941f44f1"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.25.8](https://github.com/certd/certd/compare/v1.25.7...v1.25.8) (2024-09-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.25.7](https://github.com/certd/certd/compare/v1.25.6...v1.25.7) (2024-09-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复某些地区被屏蔽无法激活专业版的bug ([7532a96](https://github.com/certd/certd/commit/7532a960851b84d4f2cc3dba02353c5235e1a364))
|
||||
|
||||
## [1.25.6](https://github.com/certd/certd/compare/v1.25.5...v1.25.6) (2024-09-29)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.25.6",
|
||||
"version": "1.25.8",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -15,7 +15,7 @@
|
||||
"test": "mocha --loader=ts-node/esm"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/plus-core": "^1.25.4",
|
||||
"@certd/plus-core": "^1.25.6",
|
||||
"axios": "^1.7.2",
|
||||
"fix-path": "^4.0.0",
|
||||
"http-proxy-agent": "^7.0.2",
|
||||
@@ -63,5 +63,5 @@
|
||||
"vite": "^4.3.8",
|
||||
"vue-tsc": "^1.6.5"
|
||||
},
|
||||
"gitHead": "be13390b3a9177c9d99f1efabfc285d0c377b013"
|
||||
"gitHead": "a7ecda9b36e318d169fe1a198fee8455941f44f1"
|
||||
}
|
||||
|
||||
@@ -27,7 +27,10 @@ export class AccessRequestHandler<T = any> {
|
||||
throw new Error("action is required");
|
||||
}
|
||||
|
||||
const methodName = `on${_.upperFirst(req.action)}`;
|
||||
let methodName = req.action;
|
||||
if (!req.action.startsWith("on")) {
|
||||
methodName = `on${_.upperFirst(req.action)}`;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const method = this[methodName];
|
||||
@@ -38,4 +41,3 @@ export class AccessRequestHandler<T = any> {
|
||||
throw new Error(`action ${req.action} not found`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { FileStore } from "../core/file-store.js";
|
||||
import { Logger } from "log4js";
|
||||
import { IAccessService } from "../access/index.js";
|
||||
import { IEmailService } from "../service/index.js";
|
||||
import { IContext, PluginRequestHandleReq } from "../core/index.js";
|
||||
import { IContext, PluginRequestHandleReq, RunnableCollection } from "../core/index.js";
|
||||
import { ILogger, logger, utils } from "../utils/index.js";
|
||||
import { HttpClient } from "../utils/util.request";
|
||||
import dayjs from "dayjs";
|
||||
@@ -165,7 +165,10 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
||||
throw new Error("action is required");
|
||||
}
|
||||
|
||||
const methodName = `on${_.upperFirst(req.action)}`;
|
||||
let methodName = req.action;
|
||||
if (!req.action.startsWith("on")) {
|
||||
methodName = `on${_.upperFirst(req.action)}`;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const method = this[methodName];
|
||||
@@ -179,6 +182,21 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
||||
isAdmin() {
|
||||
return this.ctx.user.role === "admin";
|
||||
}
|
||||
|
||||
getStepFromPipeline(stepId: string) {
|
||||
let found: any = null;
|
||||
RunnableCollection.each(this.ctx.pipeline.stages, (step) => {
|
||||
if (step.id === stepId) {
|
||||
found = step;
|
||||
return;
|
||||
}
|
||||
});
|
||||
return found;
|
||||
}
|
||||
|
||||
getStepIdFromRefInput(ref = ".") {
|
||||
return ref.split(".")[1];
|
||||
}
|
||||
}
|
||||
|
||||
export type OutputVO = {
|
||||
|
||||
@@ -5,6 +5,7 @@ export type Registrable = {
|
||||
title: string;
|
||||
desc?: string;
|
||||
group?: string;
|
||||
deprecated?: string;
|
||||
};
|
||||
|
||||
export type RegistryItem<T> = {
|
||||
@@ -67,6 +68,9 @@ export class Registry<T> {
|
||||
for (const key in this.storage) {
|
||||
const define = this.getDefine(key);
|
||||
if (define) {
|
||||
if (define?.deprecated) {
|
||||
continue;
|
||||
}
|
||||
list.push({ ...define, key });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export class HttpError extends Error {
|
||||
status?: number;
|
||||
statusText?: string;
|
||||
code?: string;
|
||||
request?: { url: string; method: string; params?: any; data?: any };
|
||||
request?: { baseURL: string; url: string; method: string; params?: any; data?: any };
|
||||
response?: { data: any };
|
||||
cause?: any;
|
||||
constructor(error: any) {
|
||||
@@ -23,6 +23,7 @@ export class HttpError extends Error {
|
||||
this.status = error.response?.status;
|
||||
this.statusText = error.response?.statusText;
|
||||
this.request = {
|
||||
baseURL: error.config?.baseURL,
|
||||
url: error.config?.url,
|
||||
method: error.config?.method,
|
||||
params: error.config?.params,
|
||||
@@ -138,6 +139,7 @@ export const http = createAxiosService({ logger }) as HttpClient;
|
||||
export type HttpClientResponse<R> = any;
|
||||
export type HttpRequestConfig<D> = {
|
||||
skipSslVerify?: boolean;
|
||||
skipCheckRes?: boolean;
|
||||
} & AxiosRequestConfig<D>;
|
||||
export type HttpClient = {
|
||||
request<D = any, R = any>(config: HttpRequestConfig<D>): Promise<HttpClientResponse<R>>;
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.25.8](https://github.com/certd/certd/compare/v1.25.7...v1.25.8) (2024-09-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.25.7](https://github.com/certd/certd/compare/v1.25.6...v1.25.7) (2024-09-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.25.6](https://github.com/certd/certd/compare/v1.25.5...v1.25.6) (2024-09-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.25.6",
|
||||
"version": "1.25.8",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
@@ -17,5 +17,5 @@
|
||||
"rimraf": "^5.0.5",
|
||||
"rollup": "^3.7.4"
|
||||
},
|
||||
"gitHead": "be13390b3a9177c9d99f1efabfc285d0c377b013"
|
||||
"gitHead": "a7ecda9b36e318d169fe1a198fee8455941f44f1"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.25.8](https://github.com/certd/certd/compare/v1.25.7...v1.25.8) (2024-09-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.25.7](https://github.com/certd/certd/compare/v1.25.6...v1.25.7) (2024-09-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.25.6](https://github.com/certd/certd/compare/v1.25.5...v1.25.6) (2024-09-29)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-iframe",
|
||||
"private": false,
|
||||
"version": "1.25.6",
|
||||
"version": "1.25.8",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -38,5 +38,5 @@
|
||||
"tslib": "^2.5.2",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "be13390b3a9177c9d99f1efabfc285d0c377b013"
|
||||
"gitHead": "a7ecda9b36e318d169fe1a198fee8455941f44f1"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.25.8](https://github.com/certd/certd/compare/v1.25.7...v1.25.8) (2024-09-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-jdcloud
|
||||
|
||||
## [1.25.7](https://github.com/certd/certd/compare/v1.25.6...v1.25.7) (2024-09-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-jdcloud
|
||||
|
||||
## [1.25.6](https://github.com/certd/certd/compare/v1.25.5...v1.25.6) (2024-09-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-jdcloud
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-jdcloud",
|
||||
"private": false,
|
||||
"version": "1.25.6",
|
||||
"version": "1.25.8",
|
||||
"main": "./dist/bundle.mjs",
|
||||
"module": "./dist/bundle.mjs",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
@@ -27,5 +27,5 @@
|
||||
"rimraf": "^5.0.5",
|
||||
"rollup": "^3.7.4"
|
||||
},
|
||||
"gitHead": "be13390b3a9177c9d99f1efabfc285d0c377b013"
|
||||
"gitHead": "a7ecda9b36e318d169fe1a198fee8455941f44f1"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.25.8](https://github.com/certd/certd/compare/v1.25.7...v1.25.8) (2024-09-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.25.7](https://github.com/certd/certd/compare/v1.25.6...v1.25.7) (2024-09-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.25.6](https://github.com/certd/certd/compare/v1.25.5...v1.25.6) (2024-09-29)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-k8s",
|
||||
"private": false,
|
||||
"version": "1.25.6",
|
||||
"version": "1.25.8",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -17,7 +17,7 @@
|
||||
"@kubernetes/client-node": "0.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/pipeline": "^1.25.6",
|
||||
"@certd/pipeline": "^1.25.8",
|
||||
"@rollup/plugin-commonjs": "^23.0.4",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
@@ -39,5 +39,5 @@
|
||||
"tslib": "^2.5.2",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "be13390b3a9177c9d99f1efabfc285d0c377b013"
|
||||
"gitHead": "a7ecda9b36e318d169fe1a198fee8455941f44f1"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.25.8](https://github.com/certd/certd/compare/v1.25.7...v1.25.8) (2024-09-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.25.7](https://github.com/certd/certd/compare/v1.25.6...v1.25.7) (2024-09-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.25.6](https://github.com/certd/certd/compare/v1.25.5...v1.25.6) (2024-09-29)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/midway-flyway-js",
|
||||
"version": "1.25.6",
|
||||
"version": "1.25.8",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -55,5 +55,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "be13390b3a9177c9d99f1efabfc285d0c377b013"
|
||||
"gitHead": "a7ecda9b36e318d169fe1a198fee8455941f44f1"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.25.8](https://github.com/certd/certd/compare/v1.25.7...v1.25.8) (2024-09-30)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复pfxPassword无效的bug ([251e450](https://github.com/certd/certd/commit/251e450fabfe62405bac13e39f2153736c081ef0))
|
||||
|
||||
## [1.25.7](https://github.com/certd/certd/compare/v1.25.6...v1.25.7) (2024-09-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.25.6](https://github.com/certd/certd/compare/v1.25.5...v1.25.6) (2024-09-29)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-cert",
|
||||
"private": false,
|
||||
"version": "1.25.6",
|
||||
"version": "1.25.8",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -14,8 +14,9 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.25.6",
|
||||
"@certd/pipeline": "^1.25.6",
|
||||
"@certd/acme-client": "^1.25.8",
|
||||
"@certd/pipeline": "^1.25.8",
|
||||
"dayjs": "^1.11.7",
|
||||
"jszip": "^3.10.1",
|
||||
"node-forge": "^0.10.0",
|
||||
"psl": "^1.9.0",
|
||||
@@ -37,7 +38,6 @@
|
||||
"@typescript-eslint/eslint-plugin": "^5.38.1",
|
||||
"@typescript-eslint/parser": "^5.38.1",
|
||||
"chai": "^4.3.6",
|
||||
"dayjs": "^1.11.6",
|
||||
"eslint": "^8.24.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
@@ -55,5 +55,5 @@
|
||||
"vite": "^3.1.0",
|
||||
"vue-tsc": "^0.38.9"
|
||||
},
|
||||
"gitHead": "be13390b3a9177c9d99f1efabfc285d0c377b013"
|
||||
"gitHead": "a7ecda9b36e318d169fe1a198fee8455941f44f1"
|
||||
}
|
||||
|
||||
@@ -65,6 +65,13 @@ export class CertReader {
|
||||
return { detail, expires };
|
||||
}
|
||||
|
||||
getAllDomains() {
|
||||
const { detail } = this.getCrtDetail();
|
||||
const domains = [detail.domains.commonName];
|
||||
domains.push(...detail.domains.altNames);
|
||||
return domains;
|
||||
}
|
||||
|
||||
saveToFile(type: "crt" | "key" | "pfx" | "der" | "ic", filepath?: string) {
|
||||
if (!this.cert[type]) {
|
||||
return;
|
||||
|
||||
@@ -21,12 +21,12 @@ export class CertConverter {
|
||||
const certReader = new CertReader(opts.cert);
|
||||
let pfxPath: string;
|
||||
let derPath: string;
|
||||
const handle = async (opts: CertReaderHandleContext) => {
|
||||
const handle = async (ctx: CertReaderHandleContext) => {
|
||||
// 调用openssl 转pfx
|
||||
pfxPath = await this.convertPfx(opts);
|
||||
pfxPath = await this.convertPfx(ctx, opts.pfxPassword);
|
||||
|
||||
// 转der
|
||||
derPath = await this.convertDer(opts);
|
||||
derPath = await this.convertDer(ctx);
|
||||
};
|
||||
|
||||
await certReader.readCertFile({ logger: this.logger, handle });
|
||||
@@ -44,7 +44,7 @@ export class CertConverter {
|
||||
});
|
||||
}
|
||||
|
||||
private async convertPfx(opts: CertReaderHandleContext, pfxPassword?: string) {
|
||||
private async convertPfx(opts: CertReaderHandleContext, pfxPassword: string) {
|
||||
const { tmpCrtPath, tmpKeyPath } = opts;
|
||||
|
||||
const pfxPath = path.join(os.tmpdir(), "/certd/tmp/", Math.floor(Math.random() * 1000000) + "", "cert.pfx");
|
||||
|
||||
@@ -174,6 +174,9 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
||||
const dnsProviderPlugin = dnsProviderRegistry.get(dnsProviderType);
|
||||
const DnsProviderClass = dnsProviderPlugin.target;
|
||||
const dnsProviderDefine = dnsProviderPlugin.define as DnsProviderDefine;
|
||||
if (dnsProviderDefine.deprecated) {
|
||||
throw new Error(dnsProviderDefine.deprecated);
|
||||
}
|
||||
const access = await this.accessService.getById(dnsProviderAccessId);
|
||||
|
||||
// @ts-ignore
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.25.8](https://github.com/certd/certd/compare/v1.25.7...v1.25.8) (2024-09-30)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 群晖获取deviceid优化 ([8d42273](https://github.com/certd/certd/commit/8d4227366548eb70f6bc04303829e6933168f906))
|
||||
|
||||
## [1.25.7](https://github.com/certd/certd/compare/v1.25.6...v1.25.7) (2024-09-29)
|
||||
|
||||
**Note:** Version bump only for package @certd/ui-client
|
||||
|
||||
## [1.25.6](https://github.com/certd/certd/compare/v1.25.5...v1.25.6) (2024-09-29)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-client",
|
||||
"version": "1.25.6",
|
||||
"version": "1.25.8",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
@@ -58,8 +58,8 @@
|
||||
"vuedraggable": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/lib-iframe": "^1.25.6",
|
||||
"@certd/pipeline": "^1.25.6",
|
||||
"@certd/lib-iframe": "^1.25.8",
|
||||
"@certd/pipeline": "^1.25.8",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.12",
|
||||
|
||||
@@ -9,7 +9,7 @@ import CronEditor from "./cron-editor/index.vue";
|
||||
import { CronLight } from "@vue-js-cron/light";
|
||||
import "@vue-js-cron/light/dist/light.css";
|
||||
import Plugins from "./plugins/index";
|
||||
import TutorialButton from "./tutorial/index.vue";
|
||||
|
||||
export default {
|
||||
install(app: any) {
|
||||
app.component("PiContainer", PiContainer);
|
||||
@@ -25,8 +25,6 @@ export default {
|
||||
app.component("InfoCircleOutlined", InfoCircleOutlined);
|
||||
app.component("UndoOutlined", UndoOutlined);
|
||||
|
||||
app.component("TutorialButton", TutorialButton);
|
||||
|
||||
app.use(vip);
|
||||
app.use(Plugins);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<script setup lang="ts">
|
||||
import { inject, ref, watch } from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
inputKey?: string;
|
||||
modelValue?: string[];
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
"update:modelValue": any;
|
||||
}>();
|
||||
|
||||
const pipeline: any = inject("pipeline");
|
||||
|
||||
function findStepFromPipeline(targetStepId: string) {
|
||||
for (const stage of pipeline.value.stages) {
|
||||
for (const task of stage.tasks) {
|
||||
for (const step of task.steps) {
|
||||
if (step.id === targetStepId) {
|
||||
return step;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const errorRef = ref("");
|
||||
function getDomainFromPipeline(inputKey: string) {
|
||||
if (!inputKey) {
|
||||
errorRef.value = "请先选择域名证书";
|
||||
return;
|
||||
}
|
||||
const targetStepId = inputKey.split(".")[1];
|
||||
const certStep = findStepFromPipeline(targetStepId);
|
||||
if (!certStep) {
|
||||
errorRef.value = "找不到目标步骤,请先选择域名证书";
|
||||
return;
|
||||
}
|
||||
const domain = certStep.input["domains"];
|
||||
emit("update:modelValue", domain);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => {
|
||||
return props.inputKey;
|
||||
},
|
||||
(inputKey: string) => {
|
||||
getDomainFromPipeline(inputKey);
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select mode="tags" readonly :value="modelValue" />
|
||||
<div>{{ errorRef }}</div>
|
||||
</template>
|
||||
|
||||
<style lang="less"></style>
|
||||
@@ -22,6 +22,19 @@ const getOptions = async () => {
|
||||
});
|
||||
};
|
||||
|
||||
const filterOption = (input: string, option: any) => {
|
||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 || String(option.value).toLowerCase().indexOf(input.toLowerCase());
|
||||
};
|
||||
|
||||
let isFirst = true;
|
||||
async function onClick() {
|
||||
if (!isFirst) {
|
||||
return;
|
||||
}
|
||||
isFirst = false;
|
||||
optionsRef.value = await getOptions();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => {
|
||||
const values = [];
|
||||
@@ -35,13 +48,20 @@ watch(
|
||||
},
|
||||
async () => {
|
||||
optionsRef.value = await getOptions();
|
||||
},
|
||||
{ immediate: true }
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select class="remote-select" :options="optionsRef" :value="value" @update:value="emit('update:value', $event)" />
|
||||
<a-select
|
||||
class="remote-select"
|
||||
show-search
|
||||
:filter-option="filterOption"
|
||||
:options="optionsRef"
|
||||
:value="value"
|
||||
@click="onClick"
|
||||
@update:value="emit('update:value', $event)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style lang="less"></style>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import SynologyIdDeviceGetter from "./synology/device-id-getter.vue";
|
||||
import RemoteSelect from "./common/remote-select.vue";
|
||||
import CertDomainsGetter from "./common/cert-domains-getter.vue";
|
||||
export default {
|
||||
install(app: any) {
|
||||
app.component("SynologyDeviceIdGetter", SynologyIdDeviceGetter);
|
||||
app.component("RemoteSelect", RemoteSelect);
|
||||
app.component("CertDomainsGetter", CertDomainsGetter);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7,10 +7,10 @@ export type ComponentPropsType = {
|
||||
value?: any;
|
||||
};
|
||||
export type RequestHandleReq<T = any> = {
|
||||
type: strin;
|
||||
type: string;
|
||||
typeName: string;
|
||||
action: string;
|
||||
data: any;
|
||||
data?: any;
|
||||
input: T;
|
||||
};
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ async function loginWithOTPCode(otpCode: string) {
|
||||
data: {
|
||||
otpCode
|
||||
},
|
||||
form: props.form
|
||||
input: props.form
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,9 @@ function next() {
|
||||
|
||||
<style lang="less">
|
||||
.tutorial-modal {
|
||||
top: 50px;
|
||||
.ant-modal-body {
|
||||
height: 70vh;
|
||||
height: 80vh;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</div>
|
||||
|
||||
<div class="image-box">
|
||||
<a-image :src="currentStepItem.image" />
|
||||
<a-image :src="currentStepItem.image" :preview-mask="previewMask" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script setup lang="tsx">
|
||||
type Step = {
|
||||
title: string;
|
||||
subTitle?: string;
|
||||
@@ -256,19 +256,26 @@ function stepChanged(index: number) {
|
||||
current.value = index;
|
||||
currentItem.value = 0;
|
||||
}
|
||||
function previewMask() {
|
||||
return (
|
||||
<div title="点击放大" class="h-100 w-100">
|
||||
{" "}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.tutorial-steps {
|
||||
.step-item {
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
.text {
|
||||
width: 100%;
|
||||
width: 350px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@@ -285,10 +292,20 @@ function stepChanged(index: number) {
|
||||
background: #eee;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
img {
|
||||
height: 100%;
|
||||
.ant-image-mask {
|
||||
background: rgba(255, 255, 255, 0);
|
||||
}
|
||||
.ant-image {
|
||||
width: 100%;
|
||||
object-fit: contain;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
.desc {
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
<MenuFoldOutlined v-else />
|
||||
</div>
|
||||
<fs-menu class="header-menu" mode="horizontal" :expand-selected="false" :selectable="false" :menus="frameworkMenus" />
|
||||
<vip-button class="flex-center header-btn" mode="nav" />
|
||||
<tutorial-button class="flex-center header-btn" />
|
||||
<vip-button class="flex-center header-btn" mode="nav" />
|
||||
</div>
|
||||
<div class="header-right header-buttons">
|
||||
<!-- <button-->
|
||||
@@ -85,12 +85,12 @@ import FsThemeSet from "/@/layout/components/theme/index.vue";
|
||||
import { env } from "../utils/util.env";
|
||||
import FsThemeModeSet from "./components/theme/mode-set.vue";
|
||||
import VipButton from "/@/components/vip-button/index.vue";
|
||||
import TutorialSteps from "/@/components/tutorial/tutorial-steps.vue";
|
||||
import TutorialButton from "/@/components/tutorial/index.vue";
|
||||
export default {
|
||||
name: "LayoutFramework",
|
||||
// eslint-disable-next-line vue/no-unused-components
|
||||
components: {
|
||||
TutorialSteps,
|
||||
TutorialButton,
|
||||
FsThemeSet,
|
||||
MenuFoldOutlined,
|
||||
MenuUnfoldOutlined,
|
||||
|
||||
@@ -3,9 +3,24 @@
|
||||
#plus:
|
||||
# server:
|
||||
# baseUrl: 'http://127.0.0.1:11007'
|
||||
|
||||
#flyway:
|
||||
# scriptDir: './db/migration-pg'
|
||||
|
||||
#typeorm:
|
||||
# dataSource:
|
||||
# default:
|
||||
# type: postgres
|
||||
# host: localhost
|
||||
# port: 5433
|
||||
# username: postgres
|
||||
# password: root
|
||||
# database: postgres
|
||||
|
||||
|
||||
plus:
|
||||
server:
|
||||
baseUrl: 'https://api.ai.handsfree.work'
|
||||
baseUrls: ['https://api.ai.handsfree.work', 'https://api.ai.docmirror.cn']
|
||||
#typeorm:
|
||||
# dataSource:
|
||||
# default:
|
||||
|
||||
@@ -9,8 +9,7 @@ typeorm:
|
||||
|
||||
plus:
|
||||
server:
|
||||
baseUrl: 'https://api.ai.handsfree.work'
|
||||
|
||||
baseUrls: ['https://api.ai.handsfree.work', 'https://api.ai.docmirror.cn']
|
||||
account:
|
||||
server:
|
||||
baseUrl: 'https://ai.handsfree.work/subject'
|
||||
|
||||
@@ -3,6 +3,21 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.25.8](https://github.com/certd/certd/compare/v1.25.7...v1.25.8) (2024-09-30)
|
||||
|
||||
**Note:** Version bump only for package @certd/ui-server
|
||||
|
||||
## [1.25.7](https://github.com/certd/certd/compare/v1.25.6...v1.25.7) (2024-09-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复某些地区被屏蔽无法激活专业版的bug ([7532a96](https://github.com/certd/certd/commit/7532a960851b84d4f2cc3dba02353c5235e1a364))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 上传到主机,支持socks代理 ([d91026d](https://github.com/certd/certd/commit/d91026dc4fbfe5fedc4ee8e43dc0d08f1cf88356))
|
||||
* 支持上传到七牛云oss ([bf024bd](https://github.com/certd/certd/commit/bf024bdda8bc2a463475be5761acf0da7317a08a))
|
||||
|
||||
## [1.25.6](https://github.com/certd/certd/compare/v1.25.5...v1.25.6) (2024-09-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-server",
|
||||
"version": "1.25.6",
|
||||
"version": "1.25.8",
|
||||
"description": "fast-server base midway",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -16,21 +16,21 @@
|
||||
"build": "mwtsc --cleanOutDir --skipLibCheck",
|
||||
"build-on-docker": "node ./before-build.js && npm run build",
|
||||
"up-mw-deps": "npx midway-version -u -w",
|
||||
"heap": "clinic heapprofiler -- node ./bootstrap.js",
|
||||
"heap": "clinic heapprofiler -- node ./bootstrap.js",
|
||||
"flame": "clinic flame -- node ./bootstrap.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alicloud/cs20151215": "^3.0.3",
|
||||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@certd/acme-client": "^1.25.6",
|
||||
"@certd/lib-huawei": "^1.25.6",
|
||||
"@certd/lib-jdcloud": "^1.25.6",
|
||||
"@certd/lib-k8s": "^1.25.6",
|
||||
"@certd/midway-flyway-js": "^1.25.6",
|
||||
"@certd/pipeline": "^1.25.6",
|
||||
"@certd/plugin-cert": "^1.25.6",
|
||||
"@certd/plugin-plus": "^1.25.6",
|
||||
"@certd/plus-core": "^1.25.4",
|
||||
"@certd/acme-client": "^1.25.8",
|
||||
"@certd/lib-huawei": "^1.25.8",
|
||||
"@certd/lib-jdcloud": "^1.25.8",
|
||||
"@certd/lib-k8s": "^1.25.8",
|
||||
"@certd/midway-flyway-js": "^1.25.8",
|
||||
"@certd/pipeline": "^1.25.8",
|
||||
"@certd/plugin-cert": "^1.25.8",
|
||||
"@certd/plugin-plus": "^1.25.8",
|
||||
"@certd/plus-core": "^1.25.6",
|
||||
"@koa/cors": "^5.0.0",
|
||||
"@midwayjs/bootstrap": "^3.16.2",
|
||||
"@midwayjs/cache": "^3.14.0",
|
||||
@@ -70,6 +70,8 @@
|
||||
"querystring": "^0.2.1",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^5.0.5",
|
||||
"socks": "^2.8.3",
|
||||
"socks-proxy-agent": "^8.0.4",
|
||||
"ssh2": "^1.15.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"svg-captcha": "^1.4.0",
|
||||
|
||||
@@ -86,7 +86,7 @@ const development = {
|
||||
resetAdminPasswd: false,
|
||||
},
|
||||
plus: {
|
||||
serverBaseUrl: 'http://127.0.0.1:11007',
|
||||
serverBaseUrls: ['http://127.0.0.1:11007'],
|
||||
},
|
||||
} as MidwayConfig;
|
||||
mergeConfig(development, 'development');
|
||||
|
||||
@@ -9,8 +9,8 @@ import { logger } from '../../../utils/logger.js';
|
||||
export class PlusService {
|
||||
@Inject()
|
||||
sysSettingsService: SysSettingsService;
|
||||
@Config('plus.server.baseUrl')
|
||||
plusServerBaseUrl;
|
||||
@Config('plus.server.baseUrls')
|
||||
plusServerBaseUrls: string[];
|
||||
|
||||
plusRequestService: PlusRequestService;
|
||||
|
||||
@@ -18,7 +18,7 @@ export class PlusService {
|
||||
async init() {
|
||||
const installInfo: SysInstallInfo = await this.sysSettingsService.getSetting(SysInstallInfo);
|
||||
this.plusRequestService = new PlusRequestService({
|
||||
plusServerBaseUrl: this.plusServerBaseUrl,
|
||||
plusServerBaseUrls: this.plusServerBaseUrls,
|
||||
http: http,
|
||||
logger,
|
||||
subjectId: installInfo.siteId,
|
||||
|
||||
@@ -53,7 +53,7 @@ export class AccessController extends CrudController<AccessService> {
|
||||
}
|
||||
|
||||
@Post('/define', { summary: Constants.per.authOnly })
|
||||
async define(@Query('type') type:string) {
|
||||
async define(@Query('type') type: string) {
|
||||
const access = this.service.getDefineByType(type);
|
||||
return this.ok(access);
|
||||
}
|
||||
@@ -63,6 +63,9 @@ export class AccessController extends CrudController<AccessService> {
|
||||
const list = this.service.getDefineList();
|
||||
const dict = [];
|
||||
for (const item of list) {
|
||||
if (item?.deprecated) {
|
||||
continue;
|
||||
}
|
||||
dict.push({
|
||||
value: item.name,
|
||||
label: item.title,
|
||||
|
||||
@@ -13,7 +13,7 @@ export class DnsProviderController extends BaseController {
|
||||
service: DnsProviderService;
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Query(ALL) query:any) {
|
||||
async list(@Query(ALL) query: any) {
|
||||
query.userId = this.ctx.user.id;
|
||||
const list = this.service.getList();
|
||||
return this.ok(list);
|
||||
|
||||
@@ -37,22 +37,19 @@ export class HandleController extends BaseController {
|
||||
//@ts-ignore
|
||||
const access = new accessCls();
|
||||
|
||||
let isNew = true;
|
||||
let inputAccess = body.input.access;
|
||||
if (body.input.id > 0) {
|
||||
const oldEntity = await this.accessService.info(body.input.id);
|
||||
if (!oldEntity) {
|
||||
isNew = false;
|
||||
const param = {
|
||||
if (oldEntity) {
|
||||
const param: any = {
|
||||
type: body.typeName,
|
||||
setting: JSON.stringify(body.input.access),
|
||||
};
|
||||
this.accessService.encryptSetting(param, oldEntity);
|
||||
body.input.access = JSON.parse(param.setting);
|
||||
inputAccess = this.accessService.decryptAccessEntity(param);
|
||||
}
|
||||
}
|
||||
if (isNew) {
|
||||
mergeUtils.merge(access, body.input.access);
|
||||
}
|
||||
mergeUtils.merge(access, inputAccess);
|
||||
|
||||
const ctx: AccessRequestHandleContext = {
|
||||
http: http,
|
||||
|
||||
@@ -60,7 +60,7 @@ export class AccessService extends BaseService<AccessEntity> implements IAccessS
|
||||
const value = json[key];
|
||||
const accessInputDefine = accessDefine.input[key];
|
||||
if (!accessInputDefine) {
|
||||
throw new ValidateException(`授权类型${accessType}不存在字段${key}`);
|
||||
continue;
|
||||
}
|
||||
if (!accessInputDefine.encrypt || !value || typeof value !== 'string') {
|
||||
//定义无需加密、value为空、不是字符串 这些不需要加密
|
||||
@@ -108,6 +108,14 @@ export class AccessService extends BaseService<AccessEntity> implements IAccessS
|
||||
throw new Error(`该授权配置不存在,请确认是否已被删除:id=${id}`);
|
||||
}
|
||||
// const access = accessRegistry.get(entity.type);
|
||||
const setting = this.decryptAccessEntity(entity);
|
||||
return {
|
||||
id: entity.id,
|
||||
...setting,
|
||||
};
|
||||
}
|
||||
|
||||
decryptAccessEntity(entity: AccessEntity): any {
|
||||
let setting = {};
|
||||
if (entity.encryptSetting && entity.encryptSetting !== '{}') {
|
||||
setting = JSON.parse(entity.encryptSetting);
|
||||
@@ -123,10 +131,7 @@ export class AccessService extends BaseService<AccessEntity> implements IAccessS
|
||||
} else if (entity.setting) {
|
||||
setting = JSON.parse(entity.setting);
|
||||
}
|
||||
return {
|
||||
id: entity.id,
|
||||
...setting,
|
||||
};
|
||||
return setting;
|
||||
}
|
||||
|
||||
getDefineList() {
|
||||
|
||||
@@ -8,6 +8,9 @@ export class PluginService {
|
||||
const list = [];
|
||||
for (const key in collection) {
|
||||
const Plugin = collection[key];
|
||||
if (Plugin?.define?.deprecated) {
|
||||
continue;
|
||||
}
|
||||
list.push({ ...Plugin.define, key });
|
||||
}
|
||||
return list;
|
||||
|
||||
@@ -41,4 +41,7 @@ export class DemoAccess implements IAccess {
|
||||
demoKeySecret = '';
|
||||
}
|
||||
|
||||
new DemoAccess();
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
//你的实现 要去掉这个if,不然生产环境将不会显示
|
||||
new DemoAccess();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
import {
|
||||
AbstractDnsProvider,
|
||||
CreateRecordOptions,
|
||||
IsDnsProvider,
|
||||
RemoveRecordOptions,
|
||||
} from '@certd/plugin-cert';
|
||||
import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from '@certd/plugin-cert';
|
||||
import { Autowire, HttpClient, ILogger } from '@certd/pipeline';
|
||||
import { DemoAccess } from './access.js';
|
||||
|
||||
@@ -83,4 +78,7 @@ export class DemoDnsProvider extends AbstractDnsProvider<DemoRecord> {
|
||||
}
|
||||
|
||||
//TODO 实例化这个provider,将其自动注册到系统中
|
||||
new DemoDnsProvider();
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
//你的实现 要去掉这个if,不然生产环境将不会显示
|
||||
new DemoDnsProvider();
|
||||
}
|
||||
|
||||
@@ -98,4 +98,7 @@ export class DemoTestPlugin extends AbstractTaskPlugin {
|
||||
}
|
||||
}
|
||||
//TODO 这里实例化插件,进行注册
|
||||
new DemoTestPlugin();
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
//你的实现 要去掉这个if,不然生产环境将不会显示
|
||||
new DemoTestPlugin();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ export class SshAccess implements IAccess, ConnectConfig {
|
||||
host!: string;
|
||||
@AccessInput({
|
||||
title: '端口',
|
||||
value: '22',
|
||||
value: 22,
|
||||
component: {
|
||||
name: 'a-input-number',
|
||||
placeholder: '22',
|
||||
@@ -64,6 +64,17 @@ export class SshAccess implements IAccess, ConnectConfig {
|
||||
})
|
||||
passphrase!: string;
|
||||
|
||||
@AccessInput({
|
||||
title: 'socks代理',
|
||||
helper: 'socks代理配置,格式:socks5://user:password@host:port',
|
||||
component: {
|
||||
name: 'a-input',
|
||||
vModel: 'value',
|
||||
},
|
||||
encrypt: false,
|
||||
})
|
||||
socksProxy!: string;
|
||||
|
||||
@AccessInput({
|
||||
title: '是否Windows',
|
||||
helper: '如果是Windows主机,请勾选此项',
|
||||
|
||||
@@ -5,10 +5,13 @@ import * as _ from 'lodash-es';
|
||||
import { ILogger } from '@certd/pipeline';
|
||||
import { SshAccess } from '../access/index.js';
|
||||
import stripAnsi from 'strip-ansi';
|
||||
import { SocksClient } from 'socks';
|
||||
import { SocksProxy, SocksProxyType } from 'socks/typings/common/constants.js';
|
||||
|
||||
export class AsyncSsh2Client {
|
||||
conn: ssh2.Client;
|
||||
logger: ILogger;
|
||||
connConf: ssh2.ConnectConfig;
|
||||
connConf: SshAccess & ssh2.ConnectConfig;
|
||||
windows = false;
|
||||
encoding: string;
|
||||
constructor(connConf: SshAccess, logger: ILogger) {
|
||||
@@ -27,6 +30,23 @@ export class AsyncSsh2Client {
|
||||
|
||||
async connect() {
|
||||
this.logger.info(`开始连接,${this.connConf.host}:${this.connConf.port}`);
|
||||
if (this.connConf.socksProxy) {
|
||||
this.logger.info(`使用代理${this.connConf.socksProxy}`);
|
||||
if (typeof this.connConf.port === 'string') {
|
||||
this.connConf.port = parseInt(this.connConf.port);
|
||||
}
|
||||
const proxyOption: SocksProxy = this.parseSocksProxyFromUri(this.connConf.socksProxy);
|
||||
const info = await SocksClient.createConnection({
|
||||
proxy: proxyOption,
|
||||
command: 'connect',
|
||||
destination: {
|
||||
host: this.connConf.host,
|
||||
port: this.connConf.port,
|
||||
},
|
||||
});
|
||||
this.logger.info('代理连接成功');
|
||||
this.connConf.sock = info.socket;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const conn = new ssh2.Client();
|
||||
@@ -160,6 +180,26 @@ export class AsyncSsh2Client {
|
||||
this.conn.end();
|
||||
}
|
||||
}
|
||||
|
||||
private parseSocksProxyFromUri(socksProxyUri: string): SocksProxy {
|
||||
const url = new URL(socksProxyUri);
|
||||
let type: SocksProxyType = 5;
|
||||
if (url.protocol.startsWith('socks4')) {
|
||||
type = 4;
|
||||
}
|
||||
const proxy: SocksProxy = {
|
||||
host: url.hostname,
|
||||
port: parseInt(url.port),
|
||||
type,
|
||||
};
|
||||
if (url.username) {
|
||||
proxy.userId = url.username;
|
||||
}
|
||||
if (url.password) {
|
||||
proxy.password = url.password;
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
}
|
||||
|
||||
export class SshClient {
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import { AccessInput, IAccess, IsAccess } from '@certd/pipeline';
|
||||
|
||||
@IsAccess({
|
||||
name: 'qiniu',
|
||||
title: '七牛云授权',
|
||||
desc: '',
|
||||
input: {},
|
||||
})
|
||||
export class QiniuAccess implements IAccess {
|
||||
@AccessInput({
|
||||
title: 'AccessKey',
|
||||
rules: [{ required: true, message: '此项必填' }],
|
||||
helper: 'AK,前往[密钥管理](https://portal.qiniu.com/developer/user/key)获取',
|
||||
})
|
||||
accessKey!: string;
|
||||
@AccessInput({
|
||||
title: 'SecretKey',
|
||||
encrypt: true,
|
||||
helper: 'SK',
|
||||
})
|
||||
secretKey!: string;
|
||||
}
|
||||
|
||||
new QiniuAccess();
|
||||
@@ -1 +0,0 @@
|
||||
export * from './access.js';
|
||||
@@ -1,2 +1 @@
|
||||
export * from './plugin/index.js';
|
||||
export * from './access/index.js';
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
|
||||
import { QiniuAccess } from '../../access/index.js';
|
||||
import { QiniuAccess, QiniuClient } from '@certd/plugin-plus';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { doRequest, uploadCert } from '../lib/sdk.js';
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'QiniuDeployCertToCDN',
|
||||
@@ -49,24 +48,27 @@ export class QiniuDeployCertToCDN extends AbstractTaskPlugin {
|
||||
async execute(): Promise<void> {
|
||||
this.logger.info('开始部署证书到七牛云cdn');
|
||||
const access = await this.accessService.getById<QiniuAccess>(this.accessId);
|
||||
|
||||
const qiniuClient = new QiniuClient({
|
||||
http: this.ctx.http,
|
||||
access,
|
||||
});
|
||||
const url = `https://api.qiniu.com/domain/${this.domainName}/httpsconf`;
|
||||
let certId = null;
|
||||
if (typeof this.cert !== 'string') {
|
||||
// 是证书id,直接上传即可
|
||||
this.logger.info('先上传证书');
|
||||
certId = await uploadCert(this.ctx.http, access, this.cert, this.appendTimeSuffix('certd'));
|
||||
certId = await qiniuClient.uploadCert(this.cert, this.appendTimeSuffix('certd'));
|
||||
} else {
|
||||
certId = this.cert;
|
||||
}
|
||||
|
||||
//开始修改证书
|
||||
this.logger.info('开始修改证书');
|
||||
this.logger.info(`开始修改证书,certId:${certId},domain:${this.domainName}`);
|
||||
const body = {
|
||||
certID: certId,
|
||||
};
|
||||
|
||||
await doRequest(this.ctx.http, access, url, 'put', body);
|
||||
await qiniuClient.doRequest(url, 'put', body);
|
||||
|
||||
this.logger.info('部署完成');
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import { HttpClient } from '@certd/pipeline';
|
||||
import { QiniuAccess } from '../../access/index.js';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
|
||||
export async function doRequest(http: HttpClient, access: QiniuAccess, url: string, method: string, body: any) {
|
||||
const { generateAccessToken } = await import('qiniu/qiniu/util.js');
|
||||
const token = generateAccessToken(access, url);
|
||||
const res = await http.request({
|
||||
url,
|
||||
method: method,
|
||||
headers: {
|
||||
Authorization: token,
|
||||
},
|
||||
data: body,
|
||||
});
|
||||
|
||||
if (res.code !== 200 || res.error) {
|
||||
throw new Error('请求失败:' + res.error);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function uploadCert(http: HttpClient, access: QiniuAccess, cert: CertInfo, certName?: string) {
|
||||
const url = 'https://api.qiniu.com/sslcert';
|
||||
|
||||
const body = {
|
||||
name: certName,
|
||||
common_name: 'certd',
|
||||
pri: cert.key,
|
||||
ca: cert.crt,
|
||||
};
|
||||
|
||||
const res = await doRequest(http, access, url, 'post', body);
|
||||
|
||||
return res.certID;
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskOutput } from '@certd/pipeline';
|
||||
import { QiniuAccess } from '../../access/index.js';
|
||||
import { QiniuAccess, QiniuClient } from '@certd/plugin-plus';
|
||||
import { CertInfo } from '@certd/plugin-cert';
|
||||
import { uploadCert } from '../lib/sdk.js';
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: 'QiniuCertUpload',
|
||||
@@ -53,7 +52,11 @@ export class QiniuCertUpload extends AbstractTaskPlugin {
|
||||
async execute(): Promise<void> {
|
||||
this.logger.info('开始上传证书到七牛云');
|
||||
const access = (await this.accessService.getById(this.accessId)) as QiniuAccess;
|
||||
this.qiniuCertId = await uploadCert(this.ctx.http, access, this.cert, this.appendTimeSuffix(this.certName));
|
||||
const qiniuClient = new QiniuClient({
|
||||
http: this.ctx.http,
|
||||
access,
|
||||
});
|
||||
this.qiniuCertId = await qiniuClient.uploadCert(this.cert, this.appendTimeSuffix(this.certName));
|
||||
this.logger.info('上传完成,id:', this.qiniuCertId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,9 @@ import { IsAccess, AccessInput } from '@certd/pipeline';
|
||||
|
||||
@IsAccess({
|
||||
name: 'dnspod',
|
||||
title: 'dnspod',
|
||||
title: 'dnspod(已废弃)',
|
||||
desc: '腾讯云的域名解析接口已迁移到dnspod',
|
||||
deprecated: 'dnspod已废弃,请换成腾讯云',
|
||||
})
|
||||
export class DnspodAccess {
|
||||
@AccessInput({
|
||||
|
||||
@@ -6,8 +6,9 @@ import { DnspodAccess } from '../access/index.js';
|
||||
@IsDnsProvider({
|
||||
name: 'dnspod',
|
||||
title: 'dnspod(已过时,请尽快换成腾讯云)',
|
||||
desc: '请尽快换成腾讯云类型',
|
||||
desc: '已废弃,请尽快换成腾讯云类型',
|
||||
accessType: 'dnspod',
|
||||
deprecated: 'dnspod已废弃,请换成腾讯云',
|
||||
})
|
||||
export class DnspodDnsProvider extends AbstractDnsProvider {
|
||||
@Autowire()
|
||||
|
||||
4
step.md
4
step.md
@@ -13,10 +13,10 @@
|
||||
## 自动化流水线创建
|
||||
|
||||
### 1. 创建证书申请部署流水线
|
||||

|
||||

|
||||
|
||||
需要添加域名的DNS解析服务商的授权
|
||||

|
||||

|
||||
|
||||
填写accessKey和accessSecret
|
||||

|
||||
|
||||
Reference in New Issue
Block a user