Compare commits

...

20 Commits

Author SHA1 Message Date
greper fd692c237b Potential fix for code scanning alert no. 31: Incomplete string escaping or encoding
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-07-30 13:18:41 +08:00
xiaojunnuo 3fc863561a build: publish 2025-07-28 23:44:43 +08:00
xiaojunnuo 131cd94495 build: trigger build image 2025-07-28 23:44:27 +08:00
xiaojunnuo f3a90a63b6 v1.36.14 2025-07-28 23:42:30 +08:00
xiaojunnuo 2494173aec build: prepare to build 2025-07-28 23:38:49 +08:00
xiaojunnuo 866eb6241b perf: 授权管理支持模糊查询 2025-07-28 23:36:10 +08:00
xiaojunnuo 86b3df1941 perf: 运行主机脚本插件支持选择运行策略 2025-07-28 23:22:38 +08:00
xiaojunnuo e87f6d56f5 perf: cdnfly 支持 账号密码登陆授权 2025-07-28 23:20:44 +08:00
xiaojunnuo acc890730f perf: 1panel支持 currenNode 2025-07-28 22:41:45 +08:00
xiaojunnuo b0707739fd fix: 修复复制流水线为空的bug 2025-07-28 18:29:28 +08:00
xiaojunnuo 251dd1fe45 fix: 修复商用证书上传第二次运行无法使用pfx格式证书的bug 2025-07-28 16:18:49 +08:00
xiaojunnuo b9f3dc65e0 chore: 雨云ref 2025-07-25 17:29:37 +08:00
xiaojunnuo 238ad7ce51 perf: 优化start脚本 2025-07-25 16:57:21 +08:00
xiaojunnuo 99fd5fca4d chore: 2025-07-25 12:05:42 +08:00
xiaojunnuo 8eda77b76d Merge branch 'v2' into v2-dev 2025-07-25 10:18:35 +08:00
ahe 81ac240ac8 perf: 新增找回密码功能 @nicheng-he
* feat 找回密码

* 1.发送邮件时修改模版
2.重置成功时清除登陆错误次数

* 增加自助找回密码控制

* 补充接口自助找回判断
2025-07-24 16:56:22 +08:00
xiaojunnuo 6109798fab chore: 2025-07-24 16:23:13 +08:00
xiaojunnuo 95715a007d perf: k8s ack、tke 支持重启ingress 2025-07-24 16:22:07 +08:00
xiaojunnuo b33ec201ac build: publish 2025-07-23 23:41:46 +08:00
xiaojunnuo b53fbaf5b3 build: trigger build image 2025-07-23 23:41:31 +08:00
65 changed files with 621 additions and 109 deletions
+17
View File
@@ -3,6 +3,23 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
### Bug Fixes
* 修复复制流水线为空的bug ([b070773](https://github.com/certd/certd/commit/b0707739fdfbae3d78db4efd3f180db05c4e4164))
* 修复商用证书上传第二次运行无法使用pfx格式证书的bug ([251dd1f](https://github.com/certd/certd/commit/251dd1fe457a7b152f43eb6de18f7beb9f0b194e))
### Performance Improvements
* 1panel支持 currenNode ([acc8907](https://github.com/certd/certd/commit/acc890730f43d492c9b1bd3668814cf10efdf7b8))
* 授权管理支持模糊查询 ([866eb62](https://github.com/certd/certd/commit/866eb6241baa7b21f6eddc649966324c188236c6))
* 新增找回密码功能 [@nicheng-he](https://github.com/nicheng-he) ([81ac240](https://github.com/certd/certd/commit/81ac240ac84db0af2f56b6352e227ecb49f38377))
* 优化start脚本 ([238ad7c](https://github.com/certd/certd/commit/238ad7ce51f17e1098c624e7f61ee2d98de1e02d))
* 运行主机脚本插件支持选择运行策略 ([86b3df1](https://github.com/certd/certd/commit/86b3df194126476e1f58e0952a77e986f62eecce))
* cdnfly 支持 账号密码登陆授权 ([e87f6d5](https://github.com/certd/certd/commit/e87f6d56f524dbbb9e3243e382b348b6e49f0d2c))
* k8s ack、tke 支持重启ingress ([95715a0](https://github.com/certd/certd/commit/95715a007d931c64fa7dd953d94957398e00a443))
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
### Bug Fixes
+2 -3
View File
@@ -16,7 +16,6 @@ Certd® 是一个免费的全自动证书管理系统,让你的网站证书永
> 流水线数量现已调整为无限制,欢迎大家使用
## 一、特性
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
@@ -87,8 +86,8 @@ https://certd.handfree.work/
1. 【推荐】[Docker方式部署 ](https://certd.docmirror.cn/guide/install/docker/)
2. 【推荐】[宝塔面板方式部署 ](https://certd.docmirror.cn/guide/install/docker/)
3. 【推荐】[1Panel面板方式部署](https://certd.docmirror.cn/guide/install/1panel/)
4. 【推荐】[雨云一键部署](https://app.rainyun.com/apps/rca/store/6646/?ref=NzExMDQ2_) : 首充翻倍,每月仅需2.2元
[<img src="https://rainyun-apps.cn-nb1.rains3.com/materials/deploy-on-rainyun-cn.svg">](https://app.rainyun.com/apps/rca/store/6646/?ref=NzExMDQ2_)
4. 【推荐】[雨云一键部署](https://app.rainyun.com/apps/rca/store/6646/?ref=NzExMDQ2) : 首充翻倍,每月仅需2.2元
[<img src="https://rainyun-apps.cn-nb1.rains3.com/materials/deploy-on-rainyun-cn.svg">](https://app.rainyun.com/apps/rca/store/6646/?ref=NzExMDQ2)
5. 【不推荐】[源码方式部署 ](https://certd.docmirror.cn/guide/install/source/)
#### Docker镜像说明:
+1 -1
View File
@@ -1 +1 @@
00:18
23:44
+27
View File
@@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
### Bug Fixes
* 修复复制流水线为空的bug ([b070773](https://github.com/certd/certd/commit/b0707739fdfbae3d78db4efd3f180db05c4e4164))
* 修复商用证书上传第二次运行无法使用pfx格式证书的bug ([251dd1f](https://github.com/certd/certd/commit/251dd1fe457a7b152f43eb6de18f7beb9f0b194e))
### Performance Improvements
* 1panel支持 currenNode ([acc8907](https://github.com/certd/certd/commit/acc890730f43d492c9b1bd3668814cf10efdf7b8))
* 授权管理支持模糊查询 ([866eb62](https://github.com/certd/certd/commit/866eb6241baa7b21f6eddc649966324c188236c6))
* 新增找回密码功能 [@nicheng-he](https://github.com/nicheng-he) ([81ac240](https://github.com/certd/certd/commit/81ac240ac84db0af2f56b6352e227ecb49f38377))
* 优化start脚本 ([238ad7c](https://github.com/certd/certd/commit/238ad7ce51f17e1098c624e7f61ee2d98de1e02d))
* 运行主机脚本插件支持选择运行策略 ([86b3df1](https://github.com/certd/certd/commit/86b3df194126476e1f58e0952a77e986f62eecce))
* cdnfly 支持 账号密码登陆授权 ([e87f6d5](https://github.com/certd/certd/commit/e87f6d56f524dbbb9e3243e382b348b6e49f0d2c))
* k8s ack、tke 支持重启ingress ([95715a0](https://github.com/certd/certd/commit/95715a007d931c64fa7dd953d94957398e00a443))
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
### Bug Fixes
* 修复阿里云发送短信验证码失败的bug ([2e6d03f](https://github.com/certd/certd/commit/2e6d03ff001f521f57368e7a62b97ed7b122e8d0))
### Performance Improvements
* 阿里云部分插件优化 [@nicheng-he](https://github.com/nicheng-he) ([e3738f6](https://github.com/certd/certd/commit/e3738f6422270d75ec414c15a343248cc4cad6e1))
## [1.36.12](https://github.com/certd/certd/compare/v1.36.11...v1.36.12) (2025-07-22)
### Bug Fixes
+1 -1
View File
@@ -4,7 +4,7 @@
## 一、源码安装
### 环境要求
- nodejs 20 及以上
- nodejs 22 及以上
### 源码启动
```shell
# 克隆代码
+1 -1
View File
@@ -9,5 +9,5 @@
}
},
"npmClient": "pnpm",
"version": "1.36.13"
"version": "1.36.14"
}
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/publishlab/node-acme-client/compare/v1.36.13...v1.36.14) (2025-07-28)
**Note:** Version bump only for package @certd/acme-client
## [1.36.13](https://github.com/publishlab/node-acme-client/compare/v1.36.12...v1.36.13) (2025-07-23)
**Note:** Version bump only for package @certd/acme-client
+3 -3
View File
@@ -3,7 +3,7 @@
"description": "Simple and unopinionated ACME client",
"private": false,
"author": "nmorsman",
"version": "1.36.13",
"version": "1.36.14",
"type": "module",
"module": "scr/index.js",
"main": "src/index.js",
@@ -18,7 +18,7 @@
"types"
],
"dependencies": {
"@certd/basic": "^1.36.13",
"@certd/basic": "^1.36.14",
"@peculiar/x509": "^1.11.0",
"asn1js": "^3.0.5",
"axios": "^1.7.2",
@@ -69,5 +69,5 @@
"bugs": {
"url": "https://github.com/publishlab/node-acme-client/issues"
},
"gitHead": "02aeb321ced3a6ac3e24e77964c497f3cc64f6a8"
"gitHead": "f3a90a63b66646a6beddcead43b4d4df7be704fc"
}
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
**Note:** Version bump only for package @certd/basic
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
**Note:** Version bump only for package @certd/basic
+1 -1
View File
@@ -1 +1 @@
23:37
23:38
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/basic",
"private": false,
"version": "1.36.13",
"version": "1.36.14",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
@@ -45,5 +45,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "02aeb321ced3a6ac3e24e77964c497f3cc64f6a8"
"gitHead": "f3a90a63b66646a6beddcead43b4d4df7be704fc"
}
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
**Note:** Version bump only for package @certd/pipeline
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
**Note:** Version bump only for package @certd/pipeline
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/pipeline",
"private": false,
"version": "1.36.13",
"version": "1.36.14",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
@@ -17,8 +17,8 @@
"pub": "npm publish"
},
"dependencies": {
"@certd/basic": "^1.36.13",
"@certd/plus-core": "^1.36.13",
"@certd/basic": "^1.36.14",
"@certd/plus-core": "^1.36.14",
"dayjs": "^1.11.7",
"lodash-es": "^4.17.21",
"reflect-metadata": "^0.1.13"
@@ -44,5 +44,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "02aeb321ced3a6ac3e24e77964c497f3cc64f6a8"
"gitHead": "f3a90a63b66646a6beddcead43b4d4df7be704fc"
}
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
**Note:** Version bump only for package @certd/lib-huawei
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
**Note:** Version bump only for package @certd/lib-huawei
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/lib-huawei",
"private": false,
"version": "1.36.13",
"version": "1.36.14",
"main": "./dist/bundle.js",
"module": "./dist/bundle.js",
"types": "./dist/d/index.d.ts",
@@ -24,5 +24,5 @@
"prettier": "^2.8.8",
"tslib": "^2.8.1"
},
"gitHead": "02aeb321ced3a6ac3e24e77964c497f3cc64f6a8"
"gitHead": "f3a90a63b66646a6beddcead43b4d4df7be704fc"
}
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
**Note:** Version bump only for package @certd/lib-iframe
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
**Note:** Version bump only for package @certd/lib-iframe
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/lib-iframe",
"private": false,
"version": "1.36.13",
"version": "1.36.14",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
@@ -31,5 +31,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "02aeb321ced3a6ac3e24e77964c497f3cc64f6a8"
"gitHead": "f3a90a63b66646a6beddcead43b4d4df7be704fc"
}
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
**Note:** Version bump only for package @certd/jdcloud
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
**Note:** Version bump only for package @certd/jdcloud
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/jdcloud",
"version": "1.36.13",
"version": "1.36.14",
"description": "jdcloud openApi sdk",
"main": "./dist/bundle.js",
"module": "./dist/bundle.js",
@@ -61,5 +61,5 @@
"fetch"
]
},
"gitHead": "02aeb321ced3a6ac3e24e77964c497f3cc64f6a8"
"gitHead": "f3a90a63b66646a6beddcead43b4d4df7be704fc"
}
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
### Performance Improvements
* k8s ack、tke 支持重启ingress ([95715a0](https://github.com/certd/certd/commit/95715a007d931c64fa7dd953d94957398e00a443))
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
**Note:** Version bump only for package @certd/lib-k8s
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/lib-k8s",
"private": false,
"version": "1.36.13",
"version": "1.36.14",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
@@ -17,7 +17,7 @@
"pub": "npm publish"
},
"dependencies": {
"@certd/basic": "^1.36.13",
"@certd/basic": "^1.36.14",
"@kubernetes/client-node": "0.21.0"
},
"devDependencies": {
@@ -32,5 +32,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "02aeb321ced3a6ac3e24e77964c497f3cc64f6a8"
"gitHead": "f3a90a63b66646a6beddcead43b4d4df7be704fc"
}
@@ -150,4 +150,18 @@ export class K8sClient {
this.logger.info("ingress patched", opts.body);
return res;
}
async restartIngress(namespace: string, ingressNames: string[], labels: any) {
const body = {
metadata: {
labels: {
...labels,
},
},
};
for (const ingress of ingressNames) {
await this.patchIngress({ namespace, ingressName: ingress, body });
this.logger.info(`ingress已重启:${ingress}`);
}
}
}
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
### Performance Improvements
* 新增找回密码功能 [@nicheng-he](https://github.com/nicheng-he) ([81ac240](https://github.com/certd/certd/commit/81ac240ac84db0af2f56b6352e227ecb49f38377))
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
**Note:** Version bump only for package @certd/lib-server
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/lib-server",
"version": "1.36.13",
"version": "1.36.14",
"description": "midway with flyway, sql upgrade way ",
"private": false,
"type": "module",
@@ -27,10 +27,10 @@
],
"license": "AGPL",
"dependencies": {
"@certd/acme-client": "^1.36.13",
"@certd/basic": "^1.36.13",
"@certd/pipeline": "^1.36.13",
"@certd/plus-core": "^1.36.13",
"@certd/acme-client": "^1.36.14",
"@certd/basic": "^1.36.14",
"@certd/pipeline": "^1.36.14",
"@certd/plus-core": "^1.36.14",
"@midwayjs/cache": "~3.14.0",
"@midwayjs/core": "~3.20.3",
"@midwayjs/i18n": "~3.20.3",
@@ -61,5 +61,5 @@
"typeorm": "^0.3.11",
"typescript": "^5.4.2"
},
"gitHead": "02aeb321ced3a6ac3e24e77964c497f3cc64f6a8"
"gitHead": "f3a90a63b66646a6beddcead43b4d4df7be704fc"
}
@@ -22,6 +22,7 @@ export class SysPublicSettings extends BaseSettings {
mobileRegisterEnabled = false;
smsLoginEnabled = false;
emailRegisterEnabled = false;
selfServicePasswordRetrievalEnabled = false;
limitUserPipelineCount = 0;
managerOtherUserPipeline = false;
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
**Note:** Version bump only for package @certd/midway-flyway-js
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
**Note:** Version bump only for package @certd/midway-flyway-js
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/midway-flyway-js",
"version": "1.36.13",
"version": "1.36.14",
"description": "midway with flyway, sql upgrade way ",
"private": false,
"type": "module",
@@ -46,5 +46,5 @@
"typeorm": "^0.3.11",
"typescript": "^5.4.2"
},
"gitHead": "02aeb321ced3a6ac3e24e77964c497f3cc64f6a8"
"gitHead": "f3a90a63b66646a6beddcead43b4d4df7be704fc"
}
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
### Bug Fixes
* 修复商用证书上传第二次运行无法使用pfx格式证书的bug ([251dd1f](https://github.com/certd/certd/commit/251dd1fe457a7b152f43eb6de18f7beb9f0b194e))
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
**Note:** Version bump only for package @certd/plugin-cert
+6 -6
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-cert",
"private": false,
"version": "1.36.13",
"version": "1.36.14",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -16,10 +16,10 @@
"pub": "npm publish"
},
"dependencies": {
"@certd/acme-client": "^1.36.13",
"@certd/basic": "^1.36.13",
"@certd/pipeline": "^1.36.13",
"@certd/plugin-lib": "^1.36.13",
"@certd/acme-client": "^1.36.14",
"@certd/basic": "^1.36.14",
"@certd/pipeline": "^1.36.14",
"@certd/plugin-lib": "^1.36.14",
"@google-cloud/publicca": "^1.3.0",
"dayjs": "^1.11.7",
"jszip": "^3.10.1",
@@ -43,5 +43,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "02aeb321ced3a6ac3e24e77964c497f3cc64f6a8"
"gitHead": "f3a90a63b66646a6beddcead43b4d4df7be704fc"
}
@@ -194,4 +194,13 @@ cert.jksjks格式证书文件,java服务器使用
};
return newCert;
}
async readLastCert(): Promise<CertReader | undefined> {
const cert = this.lastStatus?.status?.output?.cert;
if (cert == null) {
this.logger.info("没有找到上次的证书");
return undefined;
}
return new CertReader(cert);
}
}
@@ -130,15 +130,6 @@ export abstract class CertApplyBasePlugin extends CertApplyBaseConvertPlugin {
return null;
}
async readLastCert(): Promise<CertReader | undefined> {
const cert = this.lastStatus?.status?.output?.cert;
if (cert == null) {
this.logger.info("没有找到上次的证书");
return undefined;
}
return new CertReader(cert);
}
/**
* 检查是否过期,默认提前35天
* @param expires
@@ -100,8 +100,17 @@ export class CertApplyUploadPlugin extends CertApplyBaseConvertPlugin {
async onInit(): Promise<void> {}
async getCertFromStore() {
const certReader = new CertReader(this.uploadCert);
if (!certReader.expires && certReader.expires < new Date().getTime()) {
let certReader = null;
try {
this.logger.info("读取上次证书");
certReader = await this.readLastCert();
} catch (e) {
this.logger.warn("读取cert失败:", e);
}
if (certReader == null) {
certReader = new CertReader(this.uploadCert);
}
if (!certReader.expires || certReader.expires < new Date().getTime()) {
throw new Error("证书已过期,停止部署,请重新上传证书");
}
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
### Performance Improvements
* 1panel支持 currenNode ([acc8907](https://github.com/certd/certd/commit/acc890730f43d492c9b1bd3668814cf10efdf7b8))
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
### Bug Fixes
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-lib",
"private": false,
"version": "1.36.13",
"version": "1.36.14",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -21,8 +21,8 @@
"@alicloud/pop-core": "^1.7.10",
"@alicloud/tea-util": "^1.4.10",
"@aws-sdk/client-s3": "^3.787.0",
"@certd/basic": "^1.36.13",
"@certd/pipeline": "^1.36.13",
"@certd/basic": "^1.36.14",
"@certd/pipeline": "^1.36.14",
"@kubernetes/client-node": "0.21.0",
"ali-oss": "^6.22.0",
"basic-ftp": "^5.0.5",
@@ -53,5 +53,5 @@
"tslib": "^2.8.1",
"typescript": "^5.4.2"
},
"gitHead": "02aeb321ced3a6ac3e24e77964c497f3cc64f6a8"
"gitHead": "f3a90a63b66646a6beddcead43b4d4df7be704fc"
}
@@ -17,7 +17,7 @@ export function createCertDomainGetterInputDefine(opts?: { certInputKey?: string
}
}
`,
template:false,
template: false,
required: true,
},
opts?.props
@@ -42,6 +42,7 @@ export function createRemoteSelectInputDefine(opts?: {
search?: boolean;
pager?: boolean;
component?: any;
value?: any;
}) {
const title = opts?.title || "请选择";
const certDomainsInputKey = opts?.certDomainsInputKey || "certDomains";
@@ -74,6 +75,7 @@ export function createRemoteSelectInputDefine(opts?: {
watches: [certDomainsInputKey, accessIdInputKey, ...watches],
...opts.component,
},
value: opts.value,
rules: opts?.rules,
required: opts.required ?? true,
mergeScript:
+11
View File
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
### Bug Fixes
* 修复复制流水线为空的bug ([b070773](https://github.com/certd/certd/commit/b0707739fdfbae3d78db4efd3f180db05c4e4164))
### Performance Improvements
* 授权管理支持模糊查询 ([866eb62](https://github.com/certd/certd/commit/866eb6241baa7b21f6eddc649966324c188236c6))
* 新增找回密码功能 [@nicheng-he](https://github.com/nicheng-he) ([81ac240](https://github.com/certd/certd/commit/81ac240ac84db0af2f56b6352e227ecb49f38377))
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
### Performance Improvements
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/ui-client",
"version": "1.36.13",
"version": "1.36.14",
"private": true,
"scripts": {
"dev": "vite --open",
@@ -103,8 +103,8 @@
"zod-defaults": "^0.1.3"
},
"devDependencies": {
"@certd/lib-iframe": "^1.36.13",
"@certd/pipeline": "^1.36.13",
"@certd/lib-iframe": "^1.36.14",
"@certd/pipeline": "^1.36.14",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"@types/chai": "^4.3.12",
@@ -57,6 +57,7 @@ export default {
passwordPlaceholder: "Please enter your password",
mobilePlaceholder: "Please enter your mobile number",
loginButton: "Log In",
forgotPassword: "Forgot password?",
forgotAdminPassword: "Forgot admin password?",
registerLink: "Register",
@@ -565,6 +565,7 @@ export default {
dualStackNetworkHelper: "If IPv6 priority is selected, enable IPv6 in docker-compose.yaml",
enableCommonCnameService: "Enable Public CNAME Service",
commonCnameHelper: "Allow use of public CNAME service. If disabled and no <router-link to='/sys/cname/provider'>custom CNAME service</router-link> is set, CNAME proxy certificate application will not work.",
enableCommonSelfServicePasswordRetrieval: "Enable self-service password recovery",
saveButton: "Save",
stopSuccess: "Stopped successfully",
google: "Google",
@@ -57,6 +57,7 @@ export default {
passwordPlaceholder: "请输入密码",
mobilePlaceholder: "请输入手机号",
loginButton: "登录",
forgotPassword: "忘记密码?",
forgotAdminPassword: "忘记管理员密码?",
registerLink: "注册",
@@ -571,6 +571,7 @@ export default {
dualStackNetworkHelper: "如果选择IPv6优先,需要在docker-compose.yaml中启用ipv6",
enableCommonCnameService: "启用公共CNAME服务",
commonCnameHelper: "是否可以使用公共CNAME服务,如果禁用,且没有设置<router-link to='/sys/cname/provider'>自定义CNAME服务</router-link>,则无法使用CNAME代理方式申请证书",
enableCommonSelfServicePasswordRetrieval: "启用自助找回密码",
saveButton: "保存",
stopSuccess: "停止成功",
google: "Google",
@@ -24,6 +24,14 @@ export const outsideResource = [
path: "/register",
component: "/framework/register/index.vue",
},
{
meta: {
title: "找回密码",
},
name: "forgotPassword",
path: "/forgotPassword",
component: "/framework/forgot-password/index.vue",
},
],
},
...errorPage,
@@ -36,6 +36,7 @@ export type SysPublicSetting = {
emailRegisterEnabled?: boolean;
passwordLoginEnabled?: boolean;
smsLoginEnabled?: boolean;
selfServicePasswordRetrievalEnabled?: boolean;
limitUserPipelineCount?: number;
managerOtherUserPipeline?: boolean;
@@ -20,6 +20,17 @@ export interface SmsLoginReq {
randomStr: string;
}
export interface ForgotPasswordReq {
forgotPasswordType: string;
input: string;
randomStr: string;
imgCode: string;
validateCode: string;
password: string;
confirmPassword: string;
}
export interface UserInfoRes {
id: string | number;
username: string;
@@ -43,6 +54,13 @@ export async function register(user: RegisterReq): Promise<UserInfoRes> {
data: user,
});
}
export async function forgotPassword(data: ForgotPasswordReq): Promise<any> {
return await request({
url: "/forgotPassword",
method: "post",
data: data,
});
}
export async function logout() {
return await request({
url: "/logout",
@@ -4,7 +4,7 @@ import router from "../../router";
import { LocalStorage } from "/src/utils/util.storage";
// @ts-ignore
import * as UserApi from "./api.user";
import { RegisterReq, SmsLoginReq } from "./api.user";
import { ForgotPasswordReq, RegisterReq, SmsLoginReq } from "./api.user";
// @ts-ignore
import { LoginReq, UserInfoRes } from "/@/store/user/api.user";
import { message, Modal, notification } from "ant-design-vue";
@@ -67,6 +67,13 @@ export const useUserStore = defineStore({
});
await router.replace("/login");
},
async forgotPassword(params: ForgotPasswordReq): Promise<any> {
await UserApi.forgotPassword(params);
notification.success({
message: "密码已重置,请登录",
});
await router.replace("/login");
},
/**
* @description: login
*/
@@ -488,7 +488,7 @@ const idMainContent = ELEMENT_ID_MAIN_CONTENT;
</template>
</LayoutContent>
<LayoutFooter v-if="footerEnable" class="hidden md:block" :fixed="footerFixed" :height="footerHeight" :show="!isFullContent" :width="footerWidth" :z-index="zIndex + 2">
<LayoutFooter v-if="footerEnable" class="hidden md:block" :fixed="footerFixed" :height="footerHeight" :show="!isFullContent" :width="footerWidth" :z-index="zIndex">
<slot name="footer"></slot>
</LayoutFooter>
</div>
@@ -57,7 +57,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
show: false,
},
search: {
show: false,
show: true,
},
form: {
wrapper: {
@@ -14,6 +14,7 @@ import { useCertUpload } from "/@/views/certd/pipeline/cert-upload/use";
import GroupSelector from "/@/views/certd/pipeline/group/group-selector.vue";
import { useCertViewer } from "/@/views/certd/pipeline/use";
import { useI18n } from "/src/locales";
import { GetDetail, GetObj } from "./api";
export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const router = useRouter();
@@ -200,7 +201,9 @@ export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys
const { ui } = useUi();
// @ts-ignore
let row = context[ui.tableColumn.row];
row = cloneDeep(row);
const info = await GetDetail(row.id);
row = info.pipeline;
row.content = JSON.parse(row.content);
row.title = row.title + "_copy";
await crudExpose.openCopy({
row: row,
@@ -0,0 +1,179 @@
<template>
<div class="main forgot-password-page">
<a-form
ref="formRef"
class="user-layout-forgot-password"
name="custom-validation"
:model="formState"
:rules="rules"
v-bind="layout"
:label-col="{ span: 6 }"
@finish="handleFinish"
@finish-failed="handleFinishFailed"
>
<a-tabs v-model:active-key="forgotPasswordType" :destroyInactiveTabPane="true">
<a-tab-pane key="email" tab="邮箱找回">
<a-form-item has-feedback name="input" label="邮箱">
<a-input v-model:value="formState.input" placeholder="邮箱" size="large" autocomplete="off">
<template #prefix>
<fs-icon icon="ion:mail-outline"></fs-icon>
</template>
</a-input>
</a-form-item>
<a-form-item has-feedback name="validateCode" label="邮件验证码">
<email-code
v-model:value="formState.validateCode"
:img-code="formState.imgCode"
:email="formState.input"
:random-str="formState.randomStr"
verification-type="forgotPassword"
/>
</a-form-item>
</a-tab-pane>
<a-tab-pane key="mobile" tab="手机号找回">
<a-form-item required has-feedback name="input" label="手机号">
<a-input v-model:value="formState.input" placeholder="手机号" autocomplete="off">
<template #prefix>
<fs-icon icon="ion:phone-portrait-outline"></fs-icon>
</template>
</a-input>
</a-form-item>
<a-form-item name="validateCode" label="手机验证码">
<sms-code
v-model:value="formState.validateCode"
:img-code="formState.imgCode"
:mobile="formState.input"
:phone-code="formState.phoneCode"
:random-str="formState.randomStr"
verification-type="forgotPassword"
/>
</a-form-item>
</a-tab-pane>
</a-tabs>
<a-form-item has-feedback name="imgCode" label="图片验证码">
<image-code ref="imageCodeRef" v-model:value="formState.imgCode" v-model:random-str="formState.randomStr"></image-code>
</a-form-item>
<a-form-item has-feedback name="password" label="新密码">
<a-input-password v-model:value="formState.password" placeholder="新密码" size="large" autocomplete="off">
<template #prefix>
<fs-icon icon="ion:lock-closed-outline"></fs-icon>
</template>
</a-input-password>
</a-form-item>
<a-form-item has-feedback name="confirmPassword" label="确认密码">
<a-input-password v-model:value="formState.confirmPassword" placeholder="确认密码" size="large" autocomplete="off">
<template #prefix>
<fs-icon icon="ion:lock-closed-outline"></fs-icon>
</template>
</a-input-password>
</a-form-item>
<a-form-item>
<a-button type="primary" size="large" html-type="submit" class="submit-button"> 找回密码</a-button>
<div class="mt-2">
<a href="https://certd.docmirror.cn/guide/use/forgotpasswd/" target="_blank"> 管理员无绑定通信方式或MFA丢失找回 </a>
</div>
</a-form-item>
</a-form>
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref, toRaw, watch } from "vue";
import ImageCode from "/@/views/framework/login/image-code.vue";
import EmailCode from "/@/views/framework/register/email-code.vue";
import SmsCode from "/@/views/framework/login/sms-code.vue";
import { utils } from "@fast-crud/fast-crud";
import { useUserStore } from "/@/store/user";
defineOptions({
name: "ForgotPasswordPage",
});
const rules = {
input: [{ required: true }],
validateCode: [{ required: true }],
imgCode: [{ required: true }, { min: 4, max: 4, message: "请输入4位图片验证码" }],
password: [
{ required: true, trigger: "change", message: "请输入密码" },
{ min: 6, message: "至少输入6位密码" },
],
confirmPassword: [
{ required: true, trigger: "change", message: "请确认密码" },
{
validator: async (rule: any, value: any) => {
if (value && value !== formState.password) {
throw new Error("两次输入密码不一致");
}
return true;
},
},
],
};
const layout = {
labelCol: {
span: 0,
},
wrapperCol: {
span: 24,
},
};
const forgotPasswordType = ref();
const userStore = useUserStore();
const formRef = ref();
const imageCodeRef = ref();
const formState: any = reactive({
input: "",
randomStr: "",
imgCode: "",
phoneCode: "86",
validateCode: "",
password: "",
confirmPassword: "",
});
// TODO
onMounted(() => {
forgotPasswordType.value = "email";
});
//
watch(forgotPasswordType, () => {
formState.input = "";
formState.validateCode = "";
imageCodeRef.value.resetImageCode();
formRef.value.clearValidate(Object.keys(formState).filter(key => !["password", "confirmPassword"].includes(key)));
});
const handleFinish = async (values: any) => {
await userStore.forgotPassword(
toRaw({
type: forgotPasswordType.value,
input: formState.input,
randomStr: formState.randomStr,
imgCode: formState.imgCode,
validateCode: formState.validateCode,
password: formState.password,
confirmPassword: formState.confirmPassword,
}) as any
);
};
const handleFinishFailed = (errors: any) => {
utils.logger.log(errors);
};
</script>
<style scoped lang="less">
.forgot-password-page {
.user-layout-forgot-password {
.submit-button {
width: 100%;
}
}
}
</style>
@@ -11,7 +11,7 @@
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs } from "vue";
import { ref, useAttrs, defineExpose } from "vue";
import { nanoid } from "nanoid";
const props = defineProps<{
@@ -32,5 +32,10 @@ function resetImageCode() {
imageCodeUrl.value = url + "?randomStr=" + randomStr;
emit("update:randomStr", randomStr);
}
defineExpose({
resetImageCode,
})
resetImageCode();
</script>
@@ -47,10 +47,10 @@
{{ t("authentication.loginButton") }}
</a-button>
<div v-if="!settingStore.isComm" class="mt-2">
<a href="https://certd.docmirror.cn/guide/use/forgotpasswd/" target="_blank">
{{ t("authentication.forgotAdminPassword") }}
</a>
<div v-if="!!settingStore.sysPublic.selfServicePasswordRetrievalEnabled" class="mt-2">
<router-link :to="{ name: 'forgotPassword' }">
{{ t("authentication.forgotPassword") }}
</router-link>
</div>
</a-form-item>
@@ -23,6 +23,7 @@ const props = defineProps<{
phoneCode?: string;
imgCode?: string;
randomStr?: string;
verificationType?: string;
}>();
const emit = defineEmits(["update:value", "change"]);
@@ -58,6 +59,7 @@ async function sendSmsCode() {
mobile: props.mobile,
imgCode: props.imgCode,
randomStr: props.randomStr,
verificationType: props.verificationType,
});
} finally {
loading.value = false;
@@ -22,6 +22,7 @@ const props = defineProps<{
email?: string;
imgCode?: string;
randomStr?: string;
verificationType?: string;
}>();
const emit = defineEmits(["update:value", "change"]);
@@ -53,6 +54,7 @@ async function sendSmsCode() {
email: props.email,
imgCode: props.imgCode,
randomStr: props.randomStr,
verificationType: props.verificationType,
});
} finally {
loading.value = false;
@@ -47,6 +47,10 @@
<div class="helper" v-html="t('certd.commonCnameHelper')"></div>
</a-form-item>
<a-form-item :label="t('certd.enableCommonSelfServicePasswordRetrieval')" :name="['public', 'selfServicePasswordRetrievalEnabled']">
<a-switch v-model:checked="formState.public.selfServicePasswordRetrievalEnabled" />
</a-form-item>
<a-form-item label=" " :colon="false" :wrapper-col="{ span: 8 }">
<a-button :loading="saveLoading" type="primary" html-type="submit">{{ t("certd.saveButton") }}</a-button>
</a-form-item>
+8
View File
@@ -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.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
### Performance Improvements
* 授权管理支持模糊查询 ([866eb62](https://github.com/certd/certd/commit/866eb6241baa7b21f6eddc649966324c188236c6))
* 新增找回密码功能 [@nicheng-he](https://github.com/nicheng-he) ([81ac240](https://github.com/certd/certd/commit/81ac240ac84db0af2f56b6352e227ecb49f38377))
* 运行主机脚本插件支持选择运行策略 ([86b3df1](https://github.com/certd/certd/commit/86b3df194126476e1f58e0952a77e986f62eecce))
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
### Performance Improvements
+14 -14
View File
@@ -1,6 +1,6 @@
{
"name": "@certd/ui-server",
"version": "1.36.13",
"version": "1.36.14",
"description": "fast-server base midway",
"private": true,
"type": "module",
@@ -42,20 +42,20 @@
"@aws-sdk/client-cloudfront": "^3.699.0",
"@aws-sdk/client-iam": "^3.699.0",
"@aws-sdk/client-s3": "^3.705.0",
"@certd/acme-client": "^1.36.13",
"@certd/basic": "^1.36.13",
"@certd/commercial-core": "^1.36.13",
"@certd/acme-client": "^1.36.14",
"@certd/basic": "^1.36.14",
"@certd/commercial-core": "^1.36.14",
"@certd/cv4pve-api-javascript": "^8.4.1",
"@certd/jdcloud": "^1.36.13",
"@certd/lib-huawei": "^1.36.13",
"@certd/lib-k8s": "^1.36.13",
"@certd/lib-server": "^1.36.13",
"@certd/midway-flyway-js": "^1.36.13",
"@certd/pipeline": "^1.36.13",
"@certd/plugin-cert": "^1.36.13",
"@certd/plugin-lib": "^1.36.13",
"@certd/plugin-plus": "^1.36.13",
"@certd/plus-core": "^1.36.13",
"@certd/jdcloud": "^1.36.14",
"@certd/lib-huawei": "^1.36.14",
"@certd/lib-k8s": "^1.36.14",
"@certd/lib-server": "^1.36.14",
"@certd/midway-flyway-js": "^1.36.14",
"@certd/pipeline": "^1.36.14",
"@certd/plugin-cert": "^1.36.14",
"@certd/plugin-lib": "^1.36.14",
"@certd/plugin-plus": "^1.36.14",
"@certd/plus-core": "^1.36.14",
"@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120",
"@huaweicloud/huaweicloud-sdk-core": "^3.1.120",
"@koa/cors": "^5.0.0",
@@ -27,6 +27,9 @@ export class EmailCodeReq {
@Rule(RuleType.string().required().max(4))
imgCode: string;
@Rule(RuleType.string())
verificationType: string;
}
/**
@@ -55,8 +58,20 @@ export class BasicController extends BaseController {
@Body(ALL)
body: EmailCodeReq
) {
const opts = {
verificationType: body.verificationType,
title: undefined,
content: undefined,
duration: undefined,
};
if(body?.verificationType === 'forgotPassword') {
opts.title = '找回密码';
opts.content = '验证码:${code}。您正在找回密码,请输入验证码并完成操作。如非本人操作请忽略';
opts.duration = 3;
}
await this.codeService.checkCaptcha(body.randomStr, body.imgCode);
await this.codeService.sendEmailCode(body.email, body.randomStr);
await this.codeService.sendEmailCode(body.email, body.randomStr, opts);
// 设置缓存内容
return this.ok(null);
}
@@ -0,0 +1,56 @@
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
import { BaseController, CommonException, Constants, SysSettingsService } from "@certd/lib-server";
import { CodeService } from '../../../modules/basic/service/code-service.js';
import { UserService } from '../../../modules/sys/authority/service/user-service.js';
import { LoginService } from "../../../modules/login/service/login-service.js";
/**
*/
@Provide()
@Controller('/api')
export class LoginController extends BaseController {
@Inject()
loginService: LoginService;
@Inject()
userService: UserService;
@Inject()
codeService: CodeService;
@Inject()
sysSettingsService: SysSettingsService;
@Post('/forgotPassword', { summary: Constants.per.guest })
public async forgotPassword(
@Body(ALL)
body: any,
) {
const sysSettings = await this.sysSettingsService.getPublicSettings();
if(!sysSettings.selfServicePasswordRetrievalEnabled) {
throw new CommonException('暂未开启自助找回');
}
if(body.type === 'email') {
this.codeService.checkEmailCode({
verificationType: 'forgotPassword',
email: body.input,
randomStr: body.randomStr,
validateCode: body.validateCode,
throwError: true,
});
} else if(body.type === 'mobile') {
await this.codeService.checkSmsCode({
verificationType: 'forgotPassword',
mobile: body.input,
randomStr: body.randomStr,
phoneCode: body.phoneCode,
smsCode: body.validateCode,
throwError: true,
});
} else {
throw new CommonException('暂不支持的找回类型,请联系管理员找回');
}
const username = await this.userService.forgotPassword(body);
username && this.loginService.clearCacheOnSuccess(username)
return this.ok();
}
}
@@ -23,8 +23,13 @@ export class AccessController extends CrudController<AccessService> {
async page(@Body(ALL) body) {
body.query = body.query ?? {};
delete body.query.userId;
body.query.userId = this.getUserId()
let name = body.query?.name;
delete body.query.name;
const buildQuery = qb => {
qb.andWhere('user_id = :userId', { userId: this.getUserId() });
if (name) {
qb.andWhere('name like :name', { name: `%${name.trim()}%` });
}
};
const res = await this.service.page({
query: body.query,
@@ -57,7 +57,15 @@ export class CodeService {
}
/**
*/
async sendSmsCode(phoneCode = '86', mobile: string, randomStr: string) {
async sendSmsCode(
phoneCode = '86',
mobile: string,
randomStr: string,
opts?: {
duration?: number,
verificationType?: string
},
) {
if (!mobile) {
throw new Error('手机号不能为空');
}
@@ -65,6 +73,8 @@ export class CodeService {
throw new Error('randomStr不能为空');
}
const duration = Math.max(Math.floor(Math.min(opts?.duration || 5, 15)), 1);
const sysSettings = await this.sysSettingsService.getPrivateSettings();
if (!sysSettings.sms?.config?.accessId) {
throw new Error('当前站点还未配置短信');
@@ -84,16 +94,29 @@ export class CodeService {
phoneCode,
});
const key = this.buildSmsCodeKey(phoneCode, mobile, randomStr);
const key = this.buildSmsCodeKey(phoneCode, mobile, randomStr, opts?.verificationType);
cache.set(key, smsCode, {
ttl: 5 * 60 * 1000, //5分钟
ttl: duration * 60 * 1000, //5分钟
});
return smsCode;
}
/**
*
* @param email
* @param randomStr
* @param opts title标题 content内容模版 duration有效时间单位分钟 verificationType验证类型
*/
async sendEmailCode(email: string, randomStr: string) {
async sendEmailCode(
email: string,
randomStr: string,
opts?: {
title?: string,
content?: string,
duration?: number,
verificationType?: string
},
) {
if (!email) {
throw new Error('Email不能为空');
}
@@ -110,15 +133,20 @@ export class CodeService {
}
const code = randomNumber(4);
const duration = Math.max(Math.floor(Math.min(opts?.duration || 5, 15)), 1);
const title = `${siteTitle}${!!opts?.title ? opts.title : '验证码'}`;
const content = !!opts.content ? this.compile(opts.content)({code, duration}) : `您的验证码是${code},请勿泄露`;
await this.emailService.send({
subject: `${siteTitle}】验证码`,
content: `您的验证码是${code},请勿泄露`,
subject: title,
content: content,
receivers: [email],
});
const key = this.buildEmailCodeKey(email, randomStr);
const key = this.buildEmailCodeKey(email, randomStr, opts?.verificationType);
cache.set(key, code, {
ttl: 5 * 60 * 1000, //5分钟
ttl: duration * 60 * 1000, //5分钟
});
return code;
}
@@ -126,20 +154,20 @@ export class CodeService {
/**
* checkSms
*/
async checkSmsCode(opts: { mobile: string; phoneCode: string; smsCode: string; randomStr: string; throwError: boolean }) {
const key = this.buildSmsCodeKey(opts.phoneCode, opts.mobile, opts.randomStr);
async checkSmsCode(opts: { mobile: string; phoneCode: string; smsCode: string; randomStr: string; verificationType?: string; throwError: boolean }) {
const key = this.buildSmsCodeKey(opts.phoneCode, opts.mobile, opts.randomStr, opts.verificationType);
if (isDev()) {
return true;
}
return this.checkValidateCode(key, opts.smsCode, opts.throwError);
}
buildSmsCodeKey(phoneCode: string, mobile: string, randomStr: string) {
return `sms:${phoneCode}${mobile}:${randomStr}`;
buildSmsCodeKey(phoneCode: string, mobile: string, randomStr: string, verificationType?: string) {
return ['sms', verificationType, phoneCode, mobile, randomStr].filter(item => !!item).join(':');
}
buildEmailCodeKey(email: string, randomStr: string) {
return `email:${email}:${randomStr}`;
buildEmailCodeKey(email: string, randomStr: string, verificationType?: string) {
return ['email', verificationType, email, randomStr].filter(item => !!item).join(':');
}
checkValidateCode(key: string, userCode: string, throwError = true) {
//验证图片验证码
@@ -154,8 +182,18 @@ export class CodeService {
return true;
}
checkEmailCode(opts: { randomStr: string; validateCode: string; email: string; throwError: boolean }) {
const key = this.buildEmailCodeKey(opts.email, opts.randomStr);
checkEmailCode(opts: { randomStr: string; validateCode: string; email: string; verificationType?: string; throwError: boolean }) {
const key = this.buildEmailCodeKey(opts.email, opts.randomStr, opts.verificationType);
return this.checkValidateCode(key, opts.validateCode, opts.throwError);
}
compile(templateString: string) {
return new Function(
"data",
` with(data || {}) {
return \`${templateString}\`;
}
`
);
}
}
@@ -461,7 +461,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
cron = cron.replace("* *", "0 0");
}
if (cron.startsWith("*")) {
cron = cron.replace("*", "0");
cron = cron.replace(/\*/g, "0");
}
const triggerId = trigger.id;
const name = this.buildCronKey(pipelineId, triggerId);
@@ -15,6 +15,7 @@ import { DbAdapter } from '../../../db/index.js';
import { simpleNanoId, utils } from '@certd/basic';
export type RegisterType = 'username' | 'mobile' | 'email';
export type ForgotPasswordType = 'mobile' | 'email';
export const AdminRoleId = 1
/**
@@ -23,7 +24,7 @@ export const AdminRoleId = 1
@Provide()
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class UserService extends BaseService<UserEntity> {
@InjectEntityModel(UserEntity)
repository: Repository<UserEntity>;
@Inject()
@@ -229,6 +230,29 @@ export class UserService extends BaseService<UserEntity> {
return newUser;
}
async forgotPassword(
data: {
type: ForgotPasswordType; input?: string, phoneCode?: string,
randomStr: string, imgCode:string, validateCode: string,
password: string, confirmPassword: string,
}
) {
if(!data.type) {
throw new CommonException('找回类型不能为空');
}
if(data.password !== data.confirmPassword) {
throw new CommonException('两次输入的密码不一致');
}
const user = await this.findOne([{ [data.type]: data.input }]);
console.log('user', user)
if(!user) {
throw new CommonException('用户不存在');
// return;
}
await this.resetPassword(user.id, data.password)
return user.username;
}
async changePassword(userId: any, form: any) {
const user = await this.info(userId);
const passwordChecked = await this.checkPassword(form.password, user.password, user.passwordVersion);
@@ -7,6 +7,7 @@ import { SshClient } from '@certd/plugin-lib';
group: pluginGroups.host.key,
desc: '可以执行重启nginx等操作让证书生效',
input: {},
showRunStrategy: true,
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
@@ -24,10 +24,10 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
component: {
name: "a-select",
vModel: "value",
options: [{ value: "nginx", label: "TLS证书格式(Nginx可用)" }, {
value: "qcloud",
label: "Opaque格式(CLB可用,原qcloud"
}]
options: [
{ value: "nginx", label: "TLS证书格式(Nginx可用)" },
{ value: "qcloud",label: "Opaque格式(CLB可用,原qcloud"}
]
},
helper: "clb将部署Opaque类型的证书,nginx类型将部署TLS证书格式",
required: true
+4 -4
View File
@@ -33,22 +33,22 @@ echo "开始构建"
echo "构建certd-client"
export NODE_OPTIONS=--max-old-space-size=32768
cd packages/ui/certd-client
npm run build
pnpm run build
cp -r dist/* ../certd-server/public
echo "构建certd-server"
cd ../certd-server
npm run build
pnpm run build
echo "构建完成"
echo "启动服务"
# 前台运行
if [ $confirmNohup != "y" ]; then
echo "当前运行模式为前台运行,ctrl+c或者关闭ssh将会停止运行"
npm run start
pnpm run start
else
echo "当前运行模式为后台运行,可以通过tail -f ./certd.log 命令查看日志"
nohup npm run start > certd.log &
nohup pnpm run start > certd.log &
fi