diff --git a/CHANGELOG.md b/CHANGELOG.md index 74f02825..83dfbcfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +### Performance Improvements + +* 登录支持双重认证 ([48aef25](https://github.com/certd/certd/commit/48aef25b3f6499d674ca4e4ef16f4c62399fb735)) +* 多重认证登录 ([0f82cf4](https://github.com/certd/certd/commit/0f82cf409bc60706ab07e4ca4f272b9a1ca7eecb)) +* 优化部署到华为云CDN,支持先上传到ccm,再使用证书id部署,修复offline状态下导致部署报错的bug ([79df39a](https://github.com/certd/certd/commit/79df39acabab10ae7e1864dadcdc186bb007a3c5)) + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) ### Bug Fixes diff --git a/build.trigger b/build.trigger index 99f02a41..09cda20d 100644 --- a/build.trigger +++ b/build.trigger @@ -1 +1 @@ -23:49 +23:37 diff --git a/docs/guide/changelogs/CHANGELOG.md b/docs/guide/changelogs/CHANGELOG.md index 74f02825..83dfbcfb 100644 --- a/docs/guide/changelogs/CHANGELOG.md +++ b/docs/guide/changelogs/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +### Performance Improvements + +* 登录支持双重认证 ([48aef25](https://github.com/certd/certd/commit/48aef25b3f6499d674ca4e4ef16f4c62399fb735)) +* 多重认证登录 ([0f82cf4](https://github.com/certd/certd/commit/0f82cf409bc60706ab07e4ca4f272b9a1ca7eecb)) +* 优化部署到华为云CDN,支持先上传到ccm,再使用证书id部署,修复offline状态下导致部署报错的bug ([79df39a](https://github.com/certd/certd/commit/79df39acabab10ae7e1864dadcdc186bb007a3c5)) + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) ### Bug Fixes diff --git a/docs/guide/feature/safe/images/2fa.png b/docs/guide/feature/safe/images/2fa.png new file mode 100644 index 00000000..87618615 Binary files /dev/null and b/docs/guide/feature/safe/images/2fa.png differ diff --git a/docs/guide/feature/safe/index.md b/docs/guide/feature/safe/index.md index f06dc18a..b578c95d 100644 --- a/docs/guide/feature/safe/index.md +++ b/docs/guide/feature/safe/index.md @@ -22,9 +22,11 @@ Certd 存储了证书以及授权等敏感数据,所以需要严格保障安 * [站点隐藏设置说明](./hidden/) ![](./images/hidden.png) -## 4、登录二次验证 +## 4、登录双重验证 -待实现 +支持2FA双重认证 + +![](./images/2fa.png) ## 5、数据库自动备份【建议开启】 * [自动备份设置说明](../../use/backup/) diff --git a/lerna.json b/lerna.json index ed19d79d..b25a3c25 100644 --- a/lerna.json +++ b/lerna.json @@ -9,5 +9,5 @@ } }, "npmClient": "pnpm", - "version": "1.33.4" + "version": "1.33.5" } diff --git a/packages/core/acme-client/CHANGELOG.md b/packages/core/acme-client/CHANGELOG.md index 3198c4c1..b64cc3c9 100644 --- a/packages/core/acme-client/CHANGELOG.md +++ b/packages/core/acme-client/CHANGELOG.md @@ -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.33.5](https://github.com/publishlab/node-acme-client/compare/v1.33.4...v1.33.5) (2025-04-17) + +**Note:** Version bump only for package @certd/acme-client + ## [1.33.4](https://github.com/publishlab/node-acme-client/compare/v1.33.3...v1.33.4) (2025-04-15) **Note:** Version bump only for package @certd/acme-client diff --git a/packages/core/acme-client/package.json b/packages/core/acme-client/package.json index 7cb07ba4..7bcab8a9 100644 --- a/packages/core/acme-client/package.json +++ b/packages/core/acme-client/package.json @@ -3,7 +3,7 @@ "description": "Simple and unopinionated ACME client", "private": false, "author": "nmorsman", - "version": "1.33.4", + "version": "1.33.5", "type": "module", "module": "scr/index.js", "main": "src/index.js", @@ -18,7 +18,7 @@ "types" ], "dependencies": { - "@certd/basic": "^1.33.4", + "@certd/basic": "^1.33.5", "@peculiar/x509": "^1.11.0", "asn1js": "^3.0.5", "axios": "^1.7.2", @@ -67,5 +67,5 @@ "bugs": { "url": "https://github.com/publishlab/node-acme-client/issues" }, - "gitHead": "5b3fb7387df65ed67811623ef9a2c5adadc8bf4f" + "gitHead": "198a97b00c75219ea8efdc6db4676158506a07c1" } diff --git a/packages/core/basic/CHANGELOG.md b/packages/core/basic/CHANGELOG.md index 50d9101e..570a5cf7 100644 --- a/packages/core/basic/CHANGELOG.md +++ b/packages/core/basic/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +### Performance Improvements + +* 多重认证登录 ([0f82cf4](https://github.com/certd/certd/commit/0f82cf409bc60706ab07e4ca4f272b9a1ca7eecb)) + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) **Note:** Version bump only for package @certd/basic diff --git a/packages/core/basic/build.md b/packages/core/basic/build.md index 179d3280..c0b0ad71 100644 --- a/packages/core/basic/build.md +++ b/packages/core/basic/build.md @@ -1 +1 @@ -23:45 +23:32 diff --git a/packages/core/basic/package.json b/packages/core/basic/package.json index 4cdc3dd0..e8bb745a 100644 --- a/packages/core/basic/package.json +++ b/packages/core/basic/package.json @@ -1,7 +1,7 @@ { "name": "@certd/basic", "private": false, - "version": "1.33.4", + "version": "1.33.5", "type": "module", "main": "./dist/index.js", "module": "./dist/index.js", @@ -44,5 +44,5 @@ "tslib": "^2.8.1", "typescript": "^5.4.2" }, - "gitHead": "5b3fb7387df65ed67811623ef9a2c5adadc8bf4f" + "gitHead": "198a97b00c75219ea8efdc6db4676158506a07c1" } diff --git a/packages/core/basic/src/utils/util.id.ts b/packages/core/basic/src/utils/util.id.ts index ba508752..4dd7d2f6 100644 --- a/packages/core/basic/src/utils/util.id.ts +++ b/packages/core/basic/src/utils/util.id.ts @@ -1,4 +1,4 @@ import { customAlphabet } from "nanoid"; export const randomNumber = customAlphabet("1234567890", 4); -export const simpleNanoId = customAlphabet("1234567890abcdefghijklmopqrstuvwxyz", 12); +export const simpleNanoId = customAlphabet("1234567890abcdefghijklmopqrstuvwxyzABCDEFGHIJKLMOPQRSTUVWXYZ", 12); diff --git a/packages/core/pipeline/CHANGELOG.md b/packages/core/pipeline/CHANGELOG.md index 51a2827e..88668f1a 100644 --- a/packages/core/pipeline/CHANGELOG.md +++ b/packages/core/pipeline/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +**Note:** Version bump only for package @certd/pipeline + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) **Note:** Version bump only for package @certd/pipeline diff --git a/packages/core/pipeline/package.json b/packages/core/pipeline/package.json index ff25809e..aa3136a6 100644 --- a/packages/core/pipeline/package.json +++ b/packages/core/pipeline/package.json @@ -1,7 +1,7 @@ { "name": "@certd/pipeline", "private": false, - "version": "1.33.4", + "version": "1.33.5", "type": "module", "main": "./dist/index.js", "module": "./dist/index.js", @@ -16,8 +16,8 @@ "test": "mocha --loader=ts-node/esm" }, "dependencies": { - "@certd/basic": "^1.33.4", - "@certd/plus-core": "^1.33.4", + "@certd/basic": "^1.33.5", + "@certd/plus-core": "^1.33.5", "dayjs": "^1.11.7", "lodash-es": "^4.17.21", "reflect-metadata": "^0.1.13" @@ -43,5 +43,5 @@ "tslib": "^2.8.1", "typescript": "^5.4.2" }, - "gitHead": "5b3fb7387df65ed67811623ef9a2c5adadc8bf4f" + "gitHead": "198a97b00c75219ea8efdc6db4676158506a07c1" } diff --git a/packages/libs/lib-huawei/CHANGELOG.md b/packages/libs/lib-huawei/CHANGELOG.md index 4eb57b53..4c522d7a 100644 --- a/packages/libs/lib-huawei/CHANGELOG.md +++ b/packages/libs/lib-huawei/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +**Note:** Version bump only for package @certd/lib-huawei + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) **Note:** Version bump only for package @certd/lib-huawei diff --git a/packages/libs/lib-huawei/package.json b/packages/libs/lib-huawei/package.json index d2efde17..96b44579 100644 --- a/packages/libs/lib-huawei/package.json +++ b/packages/libs/lib-huawei/package.json @@ -1,7 +1,7 @@ { "name": "@certd/lib-huawei", "private": false, - "version": "1.33.4", + "version": "1.33.5", "main": "./dist/bundle.js", "module": "./dist/bundle.js", "types": "./dist/d/index.d.ts", @@ -23,5 +23,5 @@ "prettier": "^2.8.8", "tslib": "^2.8.1" }, - "gitHead": "5b3fb7387df65ed67811623ef9a2c5adadc8bf4f" + "gitHead": "198a97b00c75219ea8efdc6db4676158506a07c1" } diff --git a/packages/libs/lib-iframe/CHANGELOG.md b/packages/libs/lib-iframe/CHANGELOG.md index 4863678c..2ece0a50 100644 --- a/packages/libs/lib-iframe/CHANGELOG.md +++ b/packages/libs/lib-iframe/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +**Note:** Version bump only for package @certd/lib-iframe + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) **Note:** Version bump only for package @certd/lib-iframe diff --git a/packages/libs/lib-iframe/package.json b/packages/libs/lib-iframe/package.json index 866e06fb..f5023c17 100644 --- a/packages/libs/lib-iframe/package.json +++ b/packages/libs/lib-iframe/package.json @@ -1,7 +1,7 @@ { "name": "@certd/lib-iframe", "private": false, - "version": "1.33.4", + "version": "1.33.5", "type": "module", "main": "./dist/index.js", "module": "./dist/index.js", @@ -30,5 +30,5 @@ "tslib": "^2.8.1", "typescript": "^5.4.2" }, - "gitHead": "5b3fb7387df65ed67811623ef9a2c5adadc8bf4f" + "gitHead": "198a97b00c75219ea8efdc6db4676158506a07c1" } diff --git a/packages/libs/lib-jdcloud/CHANGELOG.md b/packages/libs/lib-jdcloud/CHANGELOG.md index 83a301b1..667da009 100644 --- a/packages/libs/lib-jdcloud/CHANGELOG.md +++ b/packages/libs/lib-jdcloud/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +**Note:** Version bump only for package @certd/jdcloud + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) **Note:** Version bump only for package @certd/jdcloud diff --git a/packages/libs/lib-jdcloud/package.json b/packages/libs/lib-jdcloud/package.json index e3b95073..9d3e31b4 100644 --- a/packages/libs/lib-jdcloud/package.json +++ b/packages/libs/lib-jdcloud/package.json @@ -1,6 +1,6 @@ { "name": "@certd/jdcloud", - "version": "1.33.4", + "version": "1.33.5", "description": "jdcloud openApi sdk", "main": "./dist/bundle.js", "module": "./dist/bundle.js", @@ -60,5 +60,5 @@ "fetch" ] }, - "gitHead": "5b3fb7387df65ed67811623ef9a2c5adadc8bf4f" + "gitHead": "198a97b00c75219ea8efdc6db4676158506a07c1" } diff --git a/packages/libs/lib-k8s/CHANGELOG.md b/packages/libs/lib-k8s/CHANGELOG.md index d6939b4a..0ccce9a5 100644 --- a/packages/libs/lib-k8s/CHANGELOG.md +++ b/packages/libs/lib-k8s/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +**Note:** Version bump only for package @certd/lib-k8s + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) **Note:** Version bump only for package @certd/lib-k8s diff --git a/packages/libs/lib-k8s/package.json b/packages/libs/lib-k8s/package.json index 21b2c312..8218721d 100644 --- a/packages/libs/lib-k8s/package.json +++ b/packages/libs/lib-k8s/package.json @@ -1,7 +1,7 @@ { "name": "@certd/lib-k8s", "private": false, - "version": "1.33.4", + "version": "1.33.5", "type": "module", "main": "./dist/index.js", "module": "./dist/index.js", @@ -16,7 +16,7 @@ "preview": "vite preview" }, "dependencies": { - "@certd/basic": "^1.33.4", + "@certd/basic": "^1.33.5", "@kubernetes/client-node": "0.21.0" }, "devDependencies": { @@ -31,5 +31,5 @@ "tslib": "^2.8.1", "typescript": "^5.4.2" }, - "gitHead": "5b3fb7387df65ed67811623ef9a2c5adadc8bf4f" + "gitHead": "198a97b00c75219ea8efdc6db4676158506a07c1" } diff --git a/packages/libs/lib-server/CHANGELOG.md b/packages/libs/lib-server/CHANGELOG.md index b9fa0775..8515b7f9 100644 --- a/packages/libs/lib-server/CHANGELOG.md +++ b/packages/libs/lib-server/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +### Performance Improvements + +* 登录支持双重认证 ([48aef25](https://github.com/certd/certd/commit/48aef25b3f6499d674ca4e4ef16f4c62399fb735)) + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) **Note:** Version bump only for package @certd/lib-server diff --git a/packages/libs/lib-server/package.json b/packages/libs/lib-server/package.json index 53e7b402..573b2313 100644 --- a/packages/libs/lib-server/package.json +++ b/packages/libs/lib-server/package.json @@ -1,6 +1,6 @@ { "name": "@certd/lib-server", - "version": "1.33.4", + "version": "1.33.5", "description": "midway with flyway, sql upgrade way ", "private": false, "type": "module", @@ -27,10 +27,10 @@ ], "license": "AGPL", "dependencies": { - "@certd/acme-client": "^1.33.4", - "@certd/basic": "^1.33.4", - "@certd/pipeline": "^1.33.4", - "@certd/plus-core": "^1.33.4", + "@certd/acme-client": "^1.33.5", + "@certd/basic": "^1.33.5", + "@certd/pipeline": "^1.33.5", + "@certd/plus-core": "^1.33.5", "@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": "5b3fb7387df65ed67811623ef9a2c5adadc8bf4f" + "gitHead": "198a97b00c75219ea8efdc6db4676158506a07c1" } diff --git a/packages/libs/lib-server/src/basic/constants.ts b/packages/libs/lib-server/src/basic/constants.ts index bfdaf507..8fdc4424 100644 --- a/packages/libs/lib-server/src/basic/constants.ts +++ b/packages/libs/lib-server/src/basic/constants.ts @@ -75,6 +75,10 @@ export const Constants = { code: 10010, message: '站点已关闭', }, + need2fa:{ + code: 10020, + message: '需要2FA认证', + }, openKeyError: { code: 20000, message: 'ApiToken错误', diff --git a/packages/libs/lib-server/src/basic/exception/auth-exception.ts b/packages/libs/lib-server/src/basic/exception/auth-exception.ts index 65a25591..299abdff 100644 --- a/packages/libs/lib-server/src/basic/exception/auth-exception.ts +++ b/packages/libs/lib-server/src/basic/exception/auth-exception.ts @@ -1,10 +1,19 @@ import { Constants } from '../constants.js'; import { BaseException } from './base-exception.js'; +import { TextException } from "./common-exception.js"; /** * 授权异常 */ export class AuthException extends BaseException { - constructor(message) { + constructor(message?:string) { super('AuthException', Constants.res.auth.code, message ? message : Constants.res.auth.message); } } + + +export class Need2FAException extends TextException { + constructor(message:string,data:any) { + super('Need2FAException', Constants.res.need2fa.code, message ? message : Constants.res.need2fa.message,data); + } +} + diff --git a/packages/libs/lib-server/src/basic/exception/base-exception.ts b/packages/libs/lib-server/src/basic/exception/base-exception.ts index c74b4167..3ee44d78 100644 --- a/packages/libs/lib-server/src/basic/exception/base-exception.ts +++ b/packages/libs/lib-server/src/basic/exception/base-exception.ts @@ -3,9 +3,11 @@ */ export class BaseException extends Error { code: number; - constructor(name, code, message) { + data?:any + constructor(name, code, message,data?:any) { super(message); this.name = name; this.code = code; + this.data = data; } } diff --git a/packages/libs/lib-server/src/basic/exception/common-exception.ts b/packages/libs/lib-server/src/basic/exception/common-exception.ts index 1873d545..5e97743a 100644 --- a/packages/libs/lib-server/src/basic/exception/common-exception.ts +++ b/packages/libs/lib-server/src/basic/exception/common-exception.ts @@ -1,16 +1,23 @@ -import { Constants } from '../constants.js'; -import { BaseException } from './base-exception.js'; +import { Constants } from "../constants.js"; +import { BaseException } from "./base-exception.js"; + /** * 通用异常 */ export class CommonException extends BaseException { constructor(message) { - super('CommonException', Constants.res.error.code, message ? message : Constants.res.error.message); + super("CommonException", Constants.res.error.code, message ? message : Constants.res.error.message); } } export class CodeException extends BaseException { constructor(res: { code: number; message: string }) { - super('CodeException', res.code, res.message); + super("CodeException", res.code, res.message); + } +} + +export class TextException extends BaseException { + constructor(name, code,message, data?) { + super(name, code, message, data); } } diff --git a/packages/libs/lib-server/src/basic/result.ts b/packages/libs/lib-server/src/basic/result.ts index e5909a33..ca42e8d1 100644 --- a/packages/libs/lib-server/src/basic/result.ts +++ b/packages/libs/lib-server/src/basic/result.ts @@ -2,14 +2,15 @@ export class Result { code: number; msg: string; data: T; + constructor(code, msg, data?) { this.code = code; this.msg = msg; this.data = data; } - static error(code = 1, msg) { - return new Result(code, msg); + static error(code = 1, msg, data?: any) { + return new Result(code, msg, data); } static success(msg, data?) { diff --git a/packages/libs/midway-flyway-js/CHANGELOG.md b/packages/libs/midway-flyway-js/CHANGELOG.md index 0743a2e3..783e0747 100644 --- a/packages/libs/midway-flyway-js/CHANGELOG.md +++ b/packages/libs/midway-flyway-js/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +**Note:** Version bump only for package @certd/midway-flyway-js + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) **Note:** Version bump only for package @certd/midway-flyway-js diff --git a/packages/libs/midway-flyway-js/package.json b/packages/libs/midway-flyway-js/package.json index b5ad4809..3ebe7a10 100644 --- a/packages/libs/midway-flyway-js/package.json +++ b/packages/libs/midway-flyway-js/package.json @@ -1,6 +1,6 @@ { "name": "@certd/midway-flyway-js", - "version": "1.33.4", + "version": "1.33.5", "description": "midway with flyway, sql upgrade way ", "private": false, "type": "module", @@ -46,5 +46,5 @@ "typeorm": "^0.3.11", "typescript": "^5.4.2" }, - "gitHead": "5b3fb7387df65ed67811623ef9a2c5adadc8bf4f" + "gitHead": "198a97b00c75219ea8efdc6db4676158506a07c1" } diff --git a/packages/plugins/plugin-cert/CHANGELOG.md b/packages/plugins/plugin-cert/CHANGELOG.md index 84831a31..51fbcff5 100644 --- a/packages/plugins/plugin-cert/CHANGELOG.md +++ b/packages/plugins/plugin-cert/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +**Note:** Version bump only for package @certd/plugin-cert + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) **Note:** Version bump only for package @certd/plugin-cert diff --git a/packages/plugins/plugin-cert/package.json b/packages/plugins/plugin-cert/package.json index 656002ce..6b4a2345 100644 --- a/packages/plugins/plugin-cert/package.json +++ b/packages/plugins/plugin-cert/package.json @@ -1,7 +1,7 @@ { "name": "@certd/plugin-cert", "private": false, - "version": "1.33.4", + "version": "1.33.5", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -15,10 +15,10 @@ "preview": "vite preview" }, "dependencies": { - "@certd/acme-client": "^1.33.4", - "@certd/basic": "^1.33.4", - "@certd/pipeline": "^1.33.4", - "@certd/plugin-lib": "^1.33.4", + "@certd/acme-client": "^1.33.5", + "@certd/basic": "^1.33.5", + "@certd/pipeline": "^1.33.5", + "@certd/plugin-lib": "^1.33.5", "@google-cloud/publicca": "^1.3.0", "dayjs": "^1.11.7", "jszip": "^3.10.1", @@ -41,5 +41,5 @@ "tslib": "^2.8.1", "typescript": "^5.4.2" }, - "gitHead": "5b3fb7387df65ed67811623ef9a2c5adadc8bf4f" + "gitHead": "198a97b00c75219ea8efdc6db4676158506a07c1" } diff --git a/packages/plugins/plugin-lib/CHANGELOG.md b/packages/plugins/plugin-lib/CHANGELOG.md index f1431f32..e2bf134c 100644 --- a/packages/plugins/plugin-lib/CHANGELOG.md +++ b/packages/plugins/plugin-lib/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +**Note:** Version bump only for package @certd/plugin-lib + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) ### Performance Improvements diff --git a/packages/plugins/plugin-lib/package.json b/packages/plugins/plugin-lib/package.json index 5d8d79ab..731df87d 100644 --- a/packages/plugins/plugin-lib/package.json +++ b/packages/plugins/plugin-lib/package.json @@ -1,7 +1,7 @@ { "name": "@certd/plugin-lib", "private": false, - "version": "1.33.4", + "version": "1.33.5", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -16,8 +16,8 @@ }, "dependencies": { "@alicloud/pop-core": "^1.7.10", - "@certd/basic": "^1.33.4", - "@certd/pipeline": "^1.33.4", + "@certd/basic": "^1.33.5", + "@certd/pipeline": "^1.33.5", "@kubernetes/client-node": "0.21.0", "ali-oss": "^6.21.0", "basic-ftp": "^5.0.5", @@ -48,5 +48,5 @@ "tslib": "^2.8.1", "typescript": "^5.4.2" }, - "gitHead": "5b3fb7387df65ed67811623ef9a2c5adadc8bf4f" + "gitHead": "198a97b00c75219ea8efdc6db4676158506a07c1" } diff --git a/packages/ui/certd-client/CHANGELOG.md b/packages/ui/certd-client/CHANGELOG.md index 8b16e465..2d4a0e5d 100644 --- a/packages/ui/certd-client/CHANGELOG.md +++ b/packages/ui/certd-client/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +### Performance Improvements + +* 登录支持双重认证 ([48aef25](https://github.com/certd/certd/commit/48aef25b3f6499d674ca4e4ef16f4c62399fb735)) +* 多重认证登录 ([0f82cf4](https://github.com/certd/certd/commit/0f82cf409bc60706ab07e4ca4f272b9a1ca7eecb)) + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) ### Performance Improvements diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index 1764aafb..f9f1904b 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -1,6 +1,6 @@ { "name": "@certd/ui-client", - "version": "1.33.4", + "version": "1.33.5", "private": true, "scripts": { "dev": "vite --open", @@ -101,8 +101,8 @@ "zod-defaults": "^0.1.3" }, "devDependencies": { - "@certd/lib-iframe": "^1.33.4", - "@certd/pipeline": "^1.33.4", + "@certd/lib-iframe": "^1.33.5", + "@certd/pipeline": "^1.33.5", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", "@types/chai": "^4.3.12", diff --git a/packages/ui/certd-client/src/api/service.ts b/packages/ui/certd-client/src/api/service.ts index 0378cce7..fd108aa0 100644 --- a/packages/ui/certd-client/src/api/service.ts +++ b/packages/ui/certd-client/src/api/service.ts @@ -3,6 +3,17 @@ import { get } from "lodash-es"; import { errorLog, errorCreate } from "./tools"; import { env } from "/src/utils/util.env"; import { useUserStore } from "/@/store/user"; + +export class CodeError extends Error { + code: number; + data?: any; + constructor(message: string, code: number, data?: any) { + super(message); + this.code = code; + this.data = data; + } +} + /** * @description 创建请求实例 */ @@ -56,12 +67,13 @@ function createService() { const errorMessage = dataAxios.msg || dataAxios.message || "未知错误"; // @ts-ignore if (response?.config?.onError) { - // @ts-ignore - response.config.onError(new Error(errorMessage)); + const err = new CodeError(errorMessage, dataAxios.code, dataAxios.data); + response.config.onError(err); + return; } //@ts-ignore const showErrorNotify = response?.config?.showErrorNotify; - errorCreate(`${errorMessage}: ${response.config.url}`, showErrorNotify); + errorCreate(`${errorMessage}: ${response.config.url}`, showErrorNotify, dataAxios); return dataAxios; } } diff --git a/packages/ui/certd-client/src/api/tools.ts b/packages/ui/certd-client/src/api/tools.ts index 08d80890..a7d949f7 100644 --- a/packages/ui/certd-client/src/api/tools.ts +++ b/packages/ui/certd-client/src/api/tools.ts @@ -4,6 +4,7 @@ * @param {String} defaultValue 默认值 */ import { uiContext } from "@fast-crud/fast-crud"; +import { CodeError } from "/@/api/service"; export function parse(jsonString = "{}", defaultValue = {}) { let result = defaultValue; @@ -68,8 +69,8 @@ export function errorLog(error: any, notify = true) { * @description 创建一个错误 * @param {String} msg 错误信息 */ -export function errorCreate(msg: string, notify = true) { - const err = new Error(msg); +export function errorCreate(msg: string, notify = true, data?: any) { + const err = new CodeError(msg, data.code, data.data); console.error("errorCreate", err); if (notify) { uiContext.get().notification.error({ message: err.message }); diff --git a/packages/ui/certd-client/src/router/source/modules/certd.ts b/packages/ui/certd-client/src/router/source/modules/certd.ts index c524c01a..a9c992be 100644 --- a/packages/ui/certd-client/src/router/source/modules/certd.ts +++ b/packages/ui/certd-client/src/router/source/modules/certd.ts @@ -143,6 +143,17 @@ export const certdResources = [ keepAlive: true, }, }, + { + title: "认证安全设置", + name: "UserSecurity", + path: "/certd/mine/security", + component: "/certd/mine/security/index.vue", + meta: { + icon: "fluent:shield-keyhole-16-regular", + auth: true, + isMenu: true, + }, + }, { title: "账号信息", name: "UserProfile", diff --git a/packages/ui/certd-client/src/store/user/api.user.ts b/packages/ui/certd-client/src/store/user/api.user.ts index 670f9118..12c92517 100644 --- a/packages/ui/certd-client/src/store/user/api.user.ts +++ b/packages/ui/certd-client/src/store/user/api.user.ts @@ -66,3 +66,11 @@ export async function mine(): Promise { method: "post", }); } + +export async function loginByTwoFactor(data: any) { + return await request({ + url: "/loginByTwoFactor", + method: "post", + data, + }); +} diff --git a/packages/ui/certd-client/src/store/user/index.ts b/packages/ui/certd-client/src/store/user/index.ts index 74632966..e6f354ed 100644 --- a/packages/ui/certd-client/src/store/user/index.ts +++ b/packages/ui/certd-client/src/store/user/index.ts @@ -51,7 +51,7 @@ export const useUserStore = defineStore({ setUserInfo(info: UserInfoRes) { this.userInfo = info; const userStore = vbenUserStore(); - userStore.setUserInfo(info); + userStore.setUserInfo(info as any); LocalStorage.set(USER_INFO_KEY, info); }, resetState() { @@ -71,23 +71,18 @@ export const useUserStore = defineStore({ * @description: login */ async login(loginType: string, params: LoginReq | SmsLoginReq): Promise { - try { - let loginRes: any = null; - if (loginType === "sms") { - loginRes = await UserApi.loginBySms(params as SmsLoginReq); - } else { - loginRes = await UserApi.login(params as LoginReq); - } - - const { token, expire } = loginRes; - // save token - this.setToken(token, expire); - // get user info - return await this.onLoginSuccess(loginRes); - } catch (error) { - console.error(error); - return null; + let loginRes: any = null; + if (loginType === "sms") { + loginRes = await UserApi.loginBySms(params as SmsLoginReq); + } else { + loginRes = await UserApi.login(params as LoginReq); } + return await this.onLoginSuccess(loginRes); + }, + + async loginByTwoFactor(form: any) { + const loginRes = await UserApi.loginByTwoFactor(form); + return await this.onLoginSuccess(loginRes); }, async getUserInfoAction(): Promise { const userInfo = await UserApi.mine(); @@ -100,9 +95,13 @@ export const useUserStore = defineStore({ }, async onLoginSuccess(loginData: any) { + const { token, expire } = loginData; + // save token + this.setToken(token, expire); + // get user info // await this.getUserInfoAction(); // const userInfo = await this.getUserInfoAction(); - mitter.emit("app.login", { token: loginData }); + mitter.emit("app.login", { ...loginData }); await router.replace("/"); }, diff --git a/packages/ui/certd-client/src/style/certd.less b/packages/ui/certd-client/src/style/certd.less index 3c2f19bc..51168636 100644 --- a/packages/ui/certd-client/src/style/certd.less +++ b/packages/ui/certd-client/src/style/certd.less @@ -105,4 +105,19 @@ span.fs-icon-svg{ svg{ vertical-align:0 !important; } +} + +.fs-button{ + span{ + &:first-child{ + margin-right: 5px; + } + &:last-child{ + margin-left: 5px; + } + } + .fs-icon,.fs-button-icon{ + margin: 0 !important; + + } } \ No newline at end of file diff --git a/packages/ui/certd-client/src/views/certd/mine/security/api.ts b/packages/ui/certd-client/src/views/certd/mine/security/api.ts new file mode 100644 index 00000000..e401a80c --- /dev/null +++ b/packages/ui/certd-client/src/views/certd/mine/security/api.ts @@ -0,0 +1,47 @@ +// @ts-ignore +import { request } from "/@/api/service"; +const apiPrefix = "/user/settings"; +export type UserTwoFactorSetting = { + authenticator: { + enabled: boolean; + verified: boolean; + }; +}; + +export type AuthenticatorSaveReq = { + verifyCode?: string; +}; + +export async function TwoFactorSettingsGet() { + const res = await request({ + url: apiPrefix + "/twoFactor/get", + method: "post", + }); + if (!res) { + return {}; + } + return res as UserTwoFactorSetting; +} + +export async function TwoFactorAuthenticatorGet() { + const res = await request({ + url: apiPrefix + "/twoFactor/authenticator/qrcode", + method: "post", + }); + return res as string; //base64 +} + +export async function TwoFactorAuthenticatorSave(req: AuthenticatorSaveReq) { + return await request({ + url: apiPrefix + "/twoFactor/authenticator/save", + method: "post", + data: req, + }); +} + +export async function TwoFactorAuthenticatorOff() { + return await request({ + url: apiPrefix + "/twoFactor/authenticator/off", + method: "post", + }); +} diff --git a/packages/ui/certd-client/src/views/certd/mine/security/index.vue b/packages/ui/certd-client/src/views/certd/mine/security/index.vue new file mode 100644 index 00000000..aab10450 --- /dev/null +++ b/packages/ui/certd-client/src/views/certd/mine/security/index.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/packages/ui/certd-client/src/views/certd/pipeline/pipeline/component/task-view/index.vue b/packages/ui/certd-client/src/views/certd/pipeline/pipeline/component/task-view/index.vue index fd747f4a..6a58039a 100644 --- a/packages/ui/certd-client/src/views/certd/pipeline/pipeline/component/task-view/index.vue +++ b/packages/ui/certd-client/src/views/certd/pipeline/pipeline/component/task-view/index.vue @@ -4,10 +4,14 @@ @@ -31,13 +35,14 @@ export default { name: "PiTaskView", components: { PiStatusShow }, props: {}, + emits: ["run"], setup(props: any, ctx: any) { const taskModal = ref({ open: false, onOk() { taskViewClose(); }, - cancelText: "关闭" + cancelText: "关闭", }); const { isMobile } = usePreferences(); const tabPosition = computed(() => { @@ -65,7 +70,7 @@ export default { node: step, type: "步骤", tab: 2, - logs: [] + logs: [], }); } for (let node of nodes) { @@ -82,7 +87,7 @@ export default { list.push({ time, content, - color + color, }); } return list; @@ -111,12 +116,12 @@ export default { if (isBottom && el) { el?.scrollTo({ top: el.scrollHeight, - behavior: "smooth" + behavior: "smooth", }); } }, { - immediate: true + immediate: true, } ); } @@ -135,15 +140,21 @@ export default { taskModal.value.open = false; }; + function triggerRun(id: string) { + ctx.emit("run", id); + taskModal.value.open = false; + } + return { detail, taskModal, activeKey, taskViewOpen, taskViewClose, - tabPosition + tabPosition, + triggerRun, }; - } + }, }; @@ -154,7 +165,7 @@ export default { .tab-title-text { display: flex; - max-width: 180px; + //max-width: 180px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; diff --git a/packages/ui/certd-client/src/views/certd/pipeline/pipeline/index.vue b/packages/ui/certd-client/src/views/certd/pipeline/pipeline/index.vue index 54fdc21b..b0e3816b 100644 --- a/packages/ui/certd-client/src/views/certd/pipeline/pipeline/index.vue +++ b/packages/ui/certd-client/src/views/certd/pipeline/pipeline/index.vue @@ -249,7 +249,7 @@ - + diff --git a/packages/ui/certd-client/src/views/certd/settings/api.ts b/packages/ui/certd-client/src/views/certd/settings/api.ts deleted file mode 100644 index 295aee24..00000000 --- a/packages/ui/certd-client/src/views/certd/settings/api.ts +++ /dev/null @@ -1,26 +0,0 @@ -// @ts-ignore -import { request } from "/@/api/service"; -const apiPrefix = "/user/settings"; -export type UserSettings = { - defaultNotification?: number; - defaultCron?: string; -}; - -export async function UserSettingsGet() { - const res = await request({ - url: apiPrefix + "/getDefault", - method: "post", - }); - if (!res) { - return {}; - } - return res; -} - -export async function UserSettingsSave(setting: any) { - return await request({ - url: apiPrefix + "/saveDefault", - method: "post", - data: setting, - }); -} diff --git a/packages/ui/certd-client/src/views/certd/settings/index.vue b/packages/ui/certd-client/src/views/certd/settings/index.vue deleted file mode 100644 index f2344e22..00000000 --- a/packages/ui/certd-client/src/views/certd/settings/index.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - - - diff --git a/packages/ui/certd-client/src/views/framework/login/index.vue b/packages/ui/certd-client/src/views/framework/login/index.vue index ef8dcbe1..c31b9a67 100644 --- a/packages/ui/certd-client/src/views/framework/login/index.vue +++ b/packages/ui/certd-client/src/views/framework/login/index.vue @@ -1,14 +1,6 @@ @@ -63,6 +49,23 @@ 注册 + diff --git a/packages/ui/certd-client/src/views/sys/settings/tabs/register.vue b/packages/ui/certd-client/src/views/sys/settings/tabs/register.vue index d442c728..eb9ccec3 100644 --- a/packages/ui/certd-client/src/views/sys/settings/tabs/register.vue +++ b/packages/ui/certd-client/src/views/sys/settings/tabs/register.vue @@ -66,34 +66,34 @@ import { useSettingStore } from "/@/store/settings"; import { notification } from "ant-design-vue"; defineOptions({ - name: "SettingRegister" + name: "SettingRegister", }); const testMobile = ref(""); async function testSendSms() { if (!testMobile.value) { notification.error({ - message: "请输入测试手机号" + message: "请输入测试手机号", }); return; } await api.TestSms({ - mobile: testMobile.value + mobile: testMobile.value, }); notification.success({ - message: "发送成功" + message: "发送成功", }); } const formState = reactive>({ public: { - registerEnabled: false + registerEnabled: false, }, private: { sms: { type: "aliyun", - config: {} - } - } + config: {}, + }, + }, }); const rules = { @@ -103,13 +103,13 @@ const rules = { return Promise.reject("密码登录和手机号登录至少开启一个"); } return Promise.resolve(); - } + }, }, required: { required: true, trigger: "change", - message: "此项必填" - } + message: "此项必填", + }, }; async function smsTypeChange(value: string) { @@ -124,13 +124,13 @@ async function loadTypeDefine(type: string) { const define: any = await api.GetSmsTypeDefine(type); const keys = Object.keys(define.input); const inputs: any = {}; - keys.forEach((key) => { + keys.forEach(key => { const value = define.input[key]; value.simpleKey = key; value.key = "private.sms.config." + key; if (!value.component) { value.component = { - name: "a-input" + name: "a-input", }; } if (!value.component.name) { @@ -165,7 +165,7 @@ const onFinish = async (form: any) => { await api.SysSettingsSave(form); await settingsStore.loadSysSettings(); notification.success({ - message: "保存成功" + message: "保存成功", }); } finally { saveLoading.value = false; diff --git a/packages/ui/certd-client/src/views/sys/settings/tabs/safe.vue b/packages/ui/certd-client/src/views/sys/settings/tabs/safe.vue index 0fa9ee8e..f850c9c9 100644 --- a/packages/ui/certd-client/src/views/sys/settings/tabs/safe.vue +++ b/packages/ui/certd-client/src/views/sys/settings/tabs/safe.vue @@ -3,7 +3,10 @@

站点隐藏

- +
+ +
+
可以在平时关闭站点的可访问性,需要时再打开,增强站点安全性 @@ -52,10 +55,11 @@ import { merge } from "lodash-es"; import { Modal, notification } from "ant-design-vue"; import { request } from "/@/api/service"; import { util, utils } from "/@/utils"; +import { useSettingStore } from "/@/store/settings"; defineOptions({ name: "SettingSafe", }); - +const settingsStore = useSettingStore(); const api = { async SettingGet() { return await request({ diff --git a/packages/ui/certd-server/CHANGELOG.md b/packages/ui/certd-server/CHANGELOG.md index d4a7ce38..a495765e 100644 --- a/packages/ui/certd-server/CHANGELOG.md +++ b/packages/ui/certd-server/CHANGELOG.md @@ -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.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17) + +### Performance Improvements + +* 登录支持双重认证 ([48aef25](https://github.com/certd/certd/commit/48aef25b3f6499d674ca4e4ef16f4c62399fb735)) +* 多重认证登录 ([0f82cf4](https://github.com/certd/certd/commit/0f82cf409bc60706ab07e4ca4f272b9a1ca7eecb)) +* 优化部署到华为云CDN,支持先上传到ccm,再使用证书id部署,修复offline状态下导致部署报错的bug ([79df39a](https://github.com/certd/certd/commit/79df39acabab10ae7e1864dadcdc186bb007a3c5)) + ## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15) ### Bug Fixes diff --git a/packages/ui/certd-server/package.json b/packages/ui/certd-server/package.json index 1e571479..41b1c0f6 100644 --- a/packages/ui/certd-server/package.json +++ b/packages/ui/certd-server/package.json @@ -1,6 +1,6 @@ { "name": "@certd/ui-server", - "version": "1.33.4", + "version": "1.33.5", "description": "fast-server base midway", "private": true, "type": "module", @@ -38,19 +38,19 @@ "@aws-sdk/client-acm": "^3.699.0", "@aws-sdk/client-cloudfront": "^3.699.0", "@aws-sdk/client-s3": "^3.705.0", - "@certd/acme-client": "^1.33.4", - "@certd/basic": "^1.33.4", - "@certd/commercial-core": "^1.33.4", - "@certd/jdcloud": "^1.33.4", - "@certd/lib-huawei": "^1.33.4", - "@certd/lib-k8s": "^1.33.4", - "@certd/lib-server": "^1.33.4", - "@certd/midway-flyway-js": "^1.33.4", - "@certd/pipeline": "^1.33.4", - "@certd/plugin-cert": "^1.33.4", - "@certd/plugin-lib": "^1.33.4", - "@certd/plugin-plus": "^1.33.4", - "@certd/plus-core": "^1.33.4", + "@certd/acme-client": "^1.33.5", + "@certd/basic": "^1.33.5", + "@certd/commercial-core": "^1.33.5", + "@certd/jdcloud": "^1.33.5", + "@certd/lib-huawei": "^1.33.5", + "@certd/lib-k8s": "^1.33.5", + "@certd/lib-server": "^1.33.5", + "@certd/midway-flyway-js": "^1.33.5", + "@certd/pipeline": "^1.33.5", + "@certd/plugin-cert": "^1.33.5", + "@certd/plugin-lib": "^1.33.5", + "@certd/plugin-plus": "^1.33.5", + "@certd/plus-core": "^1.33.5", "@corsinvest/cv4pve-api-javascript": "^8.3.0", "@huaweicloud/huaweicloud-sdk-cdn": "^3.1.120", "@huaweicloud/huaweicloud-sdk-core": "^3.1.120", @@ -97,9 +97,11 @@ "nanoid": "^5.0.7", "node-forge": "^1.3.1", "nodemailer": "^6.9.16", + "otplib": "^12.0.1", "pg": "^8.12.0", "psl": "^1.9.0", "qiniu": "^7.12.0", + "qrcode": "^1.5.4", "qs": "^6.13.1", "querystring": "^0.2.1", "reflect-metadata": "^0.2.2", diff --git a/packages/ui/certd-server/src/controller/sys/settings/sys-safe-settings-controller.ts b/packages/ui/certd-server/src/controller/sys/settings/sys-safe-settings-controller.ts index 8bc963f3..892d08bf 100644 --- a/packages/ui/certd-server/src/controller/sys/settings/sys-safe-settings-controller.ts +++ b/packages/ui/certd-server/src/controller/sys/settings/sys-safe-settings-controller.ts @@ -1,7 +1,7 @@ -import {ALL, Body, Controller, Inject, Post, Provide} from '@midwayjs/core'; -import {BaseController, SysSafeSetting} from '@certd/lib-server'; -import {cloneDeep} from 'lodash-es'; -import {SafeService} from "../../../modules/sys/settings/safe-service.js"; +import { ALL, Body, Controller, Inject, Post, Provide } from "@midwayjs/core"; +import { BaseController, SysSafeSetting } from "@certd/lib-server"; +import { cloneDeep } from "lodash-es"; +import { SafeService } from "../../../modules/sys/settings/safe-service.js"; /** diff --git a/packages/ui/certd-server/src/controller/user/login/login-controller.ts b/packages/ui/certd-server/src/controller/user/login/login-controller.ts index 8e9a2663..90bbae8d 100644 --- a/packages/ui/certd-server/src/controller/user/login/login-controller.ts +++ b/packages/ui/certd-server/src/controller/user/login/login-controller.ts @@ -23,13 +23,16 @@ export class LoginController extends BaseController { user: any ) { const token = await this.loginService.loginByPassword(user); - this.ctx.cookies.set('token', token.token, { - maxAge: 1000 * token.expire, - }); - + this.writeTokenCookie(token); return this.ok(token); } + private writeTokenCookie(token: { expire: any; token: any }) { + this.ctx.cookies.set("token", token.token, { + maxAge: 1000 * token.expire + }); + } + @Post('/loginBySms', { summary: Constants.per.guest }) public async loginBySms( @Body(ALL) @@ -48,10 +51,23 @@ export class LoginController extends BaseController { randomStr: body.randomStr, }); - this.ctx.cookies.set('token', token.token, { - maxAge: 1000 * token.expire, + this.writeTokenCookie(token); + + return this.ok(token); + } + + @Post('/loginByTwoFactor', { summary: Constants.per.guest }) + public async loginByTwoFactor( + @Body(ALL) + body: any + ) { + + const token = await this.loginService.loginByTwoFactor({ + loginId: body.loginId, + verifyCode: body.verifyCode, }); + this.writeTokenCookie(token); return this.ok(token); } diff --git a/packages/ui/certd-server/src/controller/user/mine/setting-two-factor-controller.ts b/packages/ui/certd-server/src/controller/user/mine/setting-two-factor-controller.ts new file mode 100644 index 00000000..22a805d6 --- /dev/null +++ b/packages/ui/certd-server/src/controller/user/mine/setting-two-factor-controller.ts @@ -0,0 +1,75 @@ +import { ALL, Body, Controller, Inject, Post, Provide } from "@midwayjs/core"; +import { BaseController, Constants } from "@certd/lib-server"; +import { UserSettingsService } from "../../../modules/mine/service/user-settings-service.js"; +import { UserTwoFactorSetting } from "../../../modules/mine/service/models.js"; +import { merge } from "lodash-es"; +import { TwoFactorService } from "../../../modules/mine/service/two-factor-service.js"; +import {isPlus} from "@certd/plus-core"; + +/** + */ +@Provide() +@Controller("/api/user/settings/twoFactor") +export class UserTwoFactorSettingController extends BaseController { + @Inject() + service: UserSettingsService; + + @Inject() + twoFactorService: TwoFactorService; + + + + @Post("/get", { summary: Constants.per.authOnly }) + async get() { + const userId = this.getUserId(); + const setting = await this.service.getSetting(userId, UserTwoFactorSetting); + return this.ok(setting); + } + + @Post("/save", { summary: Constants.per.authOnly }) + async save(@Body(ALL) bean: any) { + if (!isPlus()) { + throw new Error('本功能需要开通专业版') + } + const userId = this.getUserId(); + const setting = new UserTwoFactorSetting(); + merge(setting, bean); + + // 禁用时清除 + if(!setting.authenticator.enabled){ + setting.authenticator.secret = null; + setting.authenticator.verified = false; + } + + await this.service.saveSetting(userId, setting); + return this.ok({}); + } + + @Post("/authenticator/qrcode", { summary: Constants.per.authOnly }) + async authenticatorQrcode() { + const userId = this.getUserId(); + const qrcode = await this.twoFactorService.getAuthenticatorQrCode(userId); + return this.ok(qrcode); + } + + @Post("/authenticator/save", { summary: Constants.per.authOnly }) + async authenticatorSave(@Body(ALL) bean: any) { + if (!isPlus()) { + throw new Error('本功能需要开通专业版') + } + const userId = this.getUserId(); + await this.twoFactorService.saveAuthenticator({ + userId, + verifyCode: bean.verifyCode, + }); + return this.ok(); + } + + @Post("/authenticator/off", { summary: Constants.per.authOnly }) + async authenticatorOff() { + const userId = this.getUserId(); + await this.twoFactorService.offAuthenticator(userId); + return this.ok(); + } + +} diff --git a/packages/ui/certd-server/src/controller/user/mine/user-settings-controller.ts b/packages/ui/certd-server/src/controller/user/mine/user-settings-controller.ts index b4a53bdc..db2a3a29 100644 --- a/packages/ui/certd-server/src/controller/user/mine/user-settings-controller.ts +++ b/packages/ui/certd-server/src/controller/user/mine/user-settings-controller.ts @@ -1,8 +1,7 @@ -import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; -import { CrudController } from '@certd/lib-server'; -import { Constants } from '@certd/lib-server'; -import { UserSettingsService } from '../../../modules/mine/service/user-settings-service.js'; -import { UserSettingsEntity } from '../../../modules/mine/entity/user-settings.js'; +import { ALL, Body, Controller, Inject, Post, Provide, Query } from "@midwayjs/core"; +import { Constants, CrudController } from "@certd/lib-server"; +import { UserSettingsService } from "../../../modules/mine/service/user-settings-service.js"; +import { UserSettingsEntity } from "../../../modules/mine/entity/user-settings.js"; /** */ @@ -66,4 +65,6 @@ export class UserSettingsController extends CrudController const entity = await this.service.getByKey(key, this.getUserId()); return this.ok(entity); } + + } diff --git a/packages/ui/certd-server/src/middleware/global-exception.ts b/packages/ui/certd-server/src/middleware/global-exception.ts index 7e8b684a..277a6ed3 100644 --- a/packages/ui/certd-server/src/middleware/global-exception.ts +++ b/packages/ui/certd-server/src/middleware/global-exception.ts @@ -1,7 +1,7 @@ import { Provide } from '@midwayjs/core'; import { IMidwayKoaContext, IWebMiddleware, NextFunction } from '@midwayjs/koa'; import { logger } from '@certd/basic'; -import { Result } from '@certd/lib-server'; +import { Result, TextException } from "@certd/lib-server"; @Provide() export class GlobalExceptionMiddleware implements IWebMiddleware { @@ -14,12 +14,15 @@ export class GlobalExceptionMiddleware implements IWebMiddleware { await next(); logger.info('请求完成:', url, Date.now() - startTime + 'ms'); } catch (err) { + if(err instanceof TextException){ + delete err.stack + } logger.error('请求异常:', url, Date.now() - startTime + 'ms', err); ctx.status = 200; if (err.code == null || typeof err.code !== 'number') { err.code = 1; } - ctx.body = Result.error(err.code, err.message); + ctx.body = Result.error(err.code, err.message,err.data); } }; } diff --git a/packages/ui/certd-server/src/modules/login/service/login-service.ts b/packages/ui/certd-server/src/modules/login/service/login-service.ts index 16c8bacc..ea86f4bd 100644 --- a/packages/ui/certd-server/src/modules/login/service/login-service.ts +++ b/packages/ui/certd-server/src/modules/login/service/login-service.ts @@ -1,14 +1,17 @@ import {Config, Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core'; import {UserService} from '../../sys/authority/service/user-service.js'; import jwt from 'jsonwebtoken'; -import {CommonException} from '@certd/lib-server'; +import {AuthException, CommonException, Need2FAException} from "@certd/lib-server"; import {RoleService} from '../../sys/authority/service/role-service.js'; import {UserEntity} from '../../sys/authority/entity/user.js'; import {SysSettingsService} from '@certd/lib-server'; import {SysPrivateSettings} from '@certd/lib-server'; -import {cache} from '@certd/basic'; +import {cache, utils} from '@certd/basic'; import {LoginErrorException} from '@certd/lib-server/dist/basic/exception/login-error-exception.js'; import {CodeService} from '../../basic/service/code-service.js'; +import {TwoFactorService} from "../../mine/service/two-factor-service.js"; +import {UserSettingsService} from '../../mine/service/user-settings-service.js'; +import {isPlus} from "@certd/plus-core"; /** * 系统用户 @@ -28,6 +31,10 @@ export class LoginService { @Inject() sysSettingsService: SysSettingsService; + @Inject() + userSettingsService: UserSettingsService; + @Inject() + twoFactorService: TwoFactorService; checkIsBlocked(username: string) { const blockDurationKey = `login_block_duration:${username}`; @@ -138,21 +145,56 @@ export class LoginService { return this.onLoginSuccess(info); } - private async onLoginSuccess(info: UserEntity) { + async checkTwoFactorEnabled(userId: number) { + //检查是否开启多重认证 + if (!isPlus()) { + return true + } + const twoFactorSetting = await this.twoFactorService.getSetting(userId) + + const authenticatorSetting = twoFactorSetting.authenticator + if (authenticatorSetting.enabled) { + //要检查 + const randomKey = utils.id.simpleNanoId(12) + cache.set(`login_2fa_code:${randomKey}`, userId, { + ttl: 60 * 1000 * 2, + }) + throw new Need2FAException('已开启多重认证,请在2分钟内输入OPT验证码',randomKey) + } + + } + + async loginByTwoFactor(req: { loginId: string; verifyCode: string }) { + //检查是否开启多重认证 + if (!isPlus()) { + throw new Error('本功能需要开通专业版') + } + const userId = cache.get(`login_2fa_code:${req.loginId}`) + if (!userId) { + throw new AuthException('已超时,请返回重新登录') + } + await this.twoFactorService.verifyAuthenticatorCode(userId, req.verifyCode) + + return this.generateToken(await this.userService.findOne(userId)) + } + + private async onLoginSuccess(info: UserEntity) { if (info.status === 0) { throw new CommonException('用户已被禁用'); } - const roleIds = await this.roleService.getRoleIdsByUserId(info.id); - return this.generateToken(info, roleIds); + await this.checkTwoFactorEnabled(info.id) + return this.generateToken(info); } + /** * 生成token * @param user 用户对象 * @param roleIds */ - async generateToken(user: UserEntity, roleIds: number[]) { + async generateToken(user: UserEntity) { + const roleIds = await this.roleService.getRoleIdsByUserId(user.id); const tokenInfo = { username: user.username, id: user.id, diff --git a/packages/ui/certd-server/src/modules/mine/service/models.ts b/packages/ui/certd-server/src/modules/mine/service/models.ts new file mode 100644 index 00000000..2d31bf10 --- /dev/null +++ b/packages/ui/certd-server/src/modules/mine/service/models.ts @@ -0,0 +1,21 @@ +import { BaseSettings } from "@certd/lib-server"; + +export type TwoFactorAuthenticator = { + enabled: boolean; + secret?: string; + type?: string; + verified?:boolean; +} + +export class UserTwoFactorSetting extends BaseSettings { + static __title__ = "用户多重认证设置"; + static __key__ = "user.two.factor"; + + authenticator: TwoFactorAuthenticator = { + enabled:false, + verified:false, + }; + +} + + diff --git a/packages/ui/certd-server/src/modules/mine/service/two-factor-service.ts b/packages/ui/certd-server/src/modules/mine/service/two-factor-service.ts new file mode 100644 index 00000000..16fb42f3 --- /dev/null +++ b/packages/ui/certd-server/src/modules/mine/service/two-factor-service.ts @@ -0,0 +1,92 @@ +import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core"; +import { UserSettingsService } from "./user-settings-service.js"; +import { UserTwoFactorSetting } from "./models.js"; +import { UserService } from "../../sys/authority/service/user-service.js"; + +/** + * 授权 + */ +@Provide() +@Scope(ScopeEnum.Request, { allowDowngrade: true }) +export class TwoFactorService { + @Inject() + userSettingsService: UserSettingsService; + @Inject() + userService: UserService; + + + async getAuthenticatorQrCode(userId: any) { + const setting = await this.getSetting(userId) + + const authenticatorSetting = setting.authenticator; + if (!authenticatorSetting.secret) { + const { authenticator } = await import("otplib"); + + authenticatorSetting.secret = authenticator.generateSecret() + await this.userSettingsService.saveSetting(userId, setting); + } + + const user = await this.userService.info(userId); + const username = user.username; + const secret = authenticatorSetting.secret; + const qrcodeContent = `otpauth://totp/Certd:${username}?secret=${secret}&issuer=Certd`; + + //生成qrcode base64 + const qrcode = await import("qrcode"); + return await qrcode.toDataURL(qrcodeContent); + + } + + async saveAuthenticator(req: { userId: any; verifyCode: any }) { + const userId = req.userId; + const { authenticator } = await import("otplib"); + const setting = await this.getSetting(userId) + + const authenticatorSetting = setting.authenticator; + if (!authenticatorSetting.secret) { + throw new Error("secret is required"); + } + const secret = authenticatorSetting.secret; + const token = req.verifyCode; + + const isValid = authenticator.verify({ token, secret }); + if (!isValid) { + throw new Error("authenticator 校验错误"); + } + + //校验成功,保存开启状态 + authenticatorSetting.enabled = true; + authenticatorSetting.verified = true; + + await this.userSettingsService.saveSetting(userId, setting); + } + + async offAuthenticator(userId:number) { + if (!userId) { + throw new Error("userId is required"); + } + + const setting = await this.getSetting(userId) + setting.authenticator.enabled = false; + setting.authenticator.verified = false; + setting.authenticator.secret = ''; + await this.userSettingsService.saveSetting(userId, setting); + } + + async getSetting(userId:number) { + return await this.userSettingsService.getSetting(userId, UserTwoFactorSetting); + + } + + async verifyAuthenticatorCode(userId: any, verifyCode: string) { + const { authenticator } = await import("otplib"); + const setting = await this.getSetting(userId) + if (!setting.authenticator.enabled) { + throw new Error("authenticator 未开启"); + } + if (!authenticator.verify({ token: verifyCode, secret: setting.authenticator.secret })) { + throw new Error("验证码错误"); + } + return true; + } +} diff --git a/packages/ui/certd-server/src/modules/mine/service/user-settings-service.ts b/packages/ui/certd-server/src/modules/mine/service/user-settings-service.ts index 70fbbf5d..852a8780 100644 --- a/packages/ui/certd-server/src/modules/mine/service/user-settings-service.ts +++ b/packages/ui/certd-server/src/modules/mine/service/user-settings-service.ts @@ -1,8 +1,9 @@ -import { Provide, Scope, ScopeEnum } from '@midwayjs/core'; -import { InjectEntityModel } from '@midwayjs/typeorm'; -import { Repository } from 'typeorm'; -import { BaseService } from '@certd/lib-server'; -import { UserSettingsEntity } from '../entity/user-settings.js'; +import { Provide, Scope, ScopeEnum } from "@midwayjs/core"; +import { InjectEntityModel } from "@midwayjs/typeorm"; +import { Repository } from "typeorm"; +import { BaseService, BaseSettings } from "@certd/lib-server"; +import { UserSettingsEntity } from "../entity/user-settings.js"; +import { merge } from "lodash-es"; /** * 授权 @@ -27,23 +28,29 @@ export class UserSettingsService extends BaseService { const setting = JSON.parse(entity.setting); return { id: entity.id, - ...setting, + ...setting }; } async getByKey(key: string, userId: number): Promise { + if(!userId){ + throw new Error('userId is required'); + } if (!key || !userId) { return null; } return await this.repository.findOne({ where: { key, - userId, - }, + userId + } }); } async getSettingByKey(key: string, userId: number): Promise { + if(!userId){ + throw new Error('userId is required'); + } const entity = await this.getByKey(key, userId); if (!entity) { return null; @@ -55,8 +62,8 @@ export class UserSettingsService extends BaseService { const entity = await this.repository.findOne({ where: { key: bean.key, - userId: bean.userId, - }, + userId: bean.userId + } }); if (entity) { entity.setting = bean.setting; @@ -66,4 +73,42 @@ export class UserSettingsService extends BaseService { await this.repository.save(bean); } } + + + async getSetting( userId: number,type: any): Promise { + if(!userId){ + throw new Error('userId is required'); + } + const key = type.__key__; + let newSetting: T = new type(); + const savedSettings = await this.getSettingByKey(key, userId); + newSetting = merge(newSetting, savedSettings); + return newSetting; + } + + async saveSetting(userId:number,bean: T) { + if(!userId){ + throw new Error('userId is required'); + } + const old = await this.getSetting(userId,bean.constructor) + bean = merge(old,bean) + + const type: any = bean.constructor; + const key = type.__key__; + if(!key){ + throw new Error(`${type.name} must have __key__`); + } + const entity = await this.getByKey(key,userId); + const newEntity = new UserSettingsEntity(); + if (entity) { + newEntity.id = entity.id; + }else{ + newEntity.key = key; + newEntity.title = type.__title__; + newEntity.userId = userId; + } + newEntity.setting = JSON.stringify(bean); + await this.repository.save(newEntity); + } + } diff --git a/packages/ui/certd-server/src/plugins/plugin-huawei/plugins/deploy-to-cdn/index.ts b/packages/ui/certd-server/src/plugins/plugin-huawei/plugins/deploy-to-cdn/index.ts index 5827b37b..32a916ef 100644 --- a/packages/ui/certd-server/src/plugins/plugin-huawei/plugins/deploy-to-cdn/index.ts +++ b/packages/ui/certd-server/src/plugins/plugin-huawei/plugins/deploy-to-cdn/index.ts @@ -22,11 +22,11 @@ export class HauweiDeployCertToCDN extends AbstractTaskPlugin { helper: '请选择前置任务输出的域名证书', component: { name: 'output-selector', - from: [...CertApplyPluginNames], + from: [...CertApplyPluginNames,'HauweiUploadToCCM'], }, required: true, }) - cert!: CertInfo; + cert!: CertInfo | string; @TaskInput(createCertDomainGetterInputDefine({ props: { required: false } })) certDomains!: string[]; @@ -53,14 +53,25 @@ export class HauweiDeployCertToCDN extends AbstractTaskPlugin { domains!: string[]; async execute(): Promise { + if (!this.cert) { + throw new Error('域名证书不能为空'); + } this.logger.info('开始部署证书到华为云cdn'); const { cdn, client } = await this.getCdnClient(); - const httpsConfig = new cdn.HttpPutBody() + let httpsConfig = new cdn.HttpPutBody() .withHttpsStatus('on') .withCertificateType('server') - .withCertificateName(this.appendTimeSuffix('certd')) - .withCertificateValue(this.cert.crt) - .withPrivateKey(this.cert.key); + + if(typeof this.cert === 'object'){ + httpsConfig= httpsConfig.withCertificateSource(0) + .withCertificateName(this.appendTimeSuffix('certd')) + .withCertificateValue(this.cert.crt) + .withPrivateKey(this.cert.key); + }else{ + this.logger.info('使用已有域名证书:', this.cert); + httpsConfig= httpsConfig.withCertificateSource(2)//scm证书 + .withScmCertificateId(this.cert) + } const config = new cdn.Configs().withHttps(httpsConfig); const body = new cdn.ModifyDomainConfigRequestBody().withConfigs(config); @@ -70,9 +81,28 @@ export class HauweiDeployCertToCDN extends AbstractTaskPlugin { this.logger.info('部署域名:', JSON.stringify(this.domains)); for (const domain of this.domains) { this.logger.info('部署到域名:', domain); - const req = new cdn.UpdateDomainFullConfigRequest().withDomainName(domain).withBody(body); - await client.updateDomainFullConfig(req); - this.logger.info(`部署到域名${domain}完成:`); + + const queryReq = new cdn.ShowDomainDetailByNameRequest(domain); + const domainDetail = await client.showDomainDetailByName(queryReq); + //@ts-ignore + const status = domainDetail.domain.domainStatus || domainDetail.domain.domain_status + this.logger.info(`当前域名状态:`, status); + let ignoreError = false + if (status === 'offline') { + ignoreError = true + } + try{ + const req = new cdn.UpdateDomainFullConfigRequest().withDomainName(domain).withBody(body); + await client.updateDomainFullConfig(req); + this.logger.info(`部署到域名${domain}完成:`); + }catch (e) { + if (ignoreError){ + this.logger.warn(`部署到域名${domain}失败,由于其处于offline状态,忽略部署错误,继续执行:`, e); + }else{ + throw e + } + } + } this.logger.info('部署证书到华为云cdn完成'); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d7f73fc7..ceafc151 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -46,7 +46,7 @@ importers: packages/core/acme-client: dependencies: '@certd/basic': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../basic '@peculiar/x509': specifier: ^1.11.0 @@ -204,11 +204,11 @@ importers: packages/core/pipeline: dependencies: '@certd/basic': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../basic '@certd/plus-core': - specifier: ^1.33.2 - version: 1.33.2 + specifier: ^1.33.4 + version: link:../../pro/plus-core dayjs: specifier: ^1.11.7 version: 1.11.13 @@ -412,7 +412,7 @@ importers: packages/libs/lib-k8s: dependencies: '@certd/basic': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/basic '@kubernetes/client-node': specifier: 0.21.0 @@ -452,17 +452,17 @@ importers: packages/libs/lib-server: dependencies: '@certd/acme-client': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/acme-client '@certd/basic': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/basic '@certd/pipeline': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/pipeline '@certd/plus-core': - specifier: ^1.33.2 - version: 1.33.2 + specifier: ^1.33.4 + version: link:../../pro/plus-core '@midwayjs/cache': specifier: ~3.14.0 version: 3.14.0 @@ -604,16 +604,16 @@ importers: packages/plugins/plugin-cert: dependencies: '@certd/acme-client': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/acme-client '@certd/basic': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/basic '@certd/pipeline': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/pipeline '@certd/plugin-lib': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../plugin-lib '@google-cloud/publicca': specifier: ^1.3.0 @@ -680,10 +680,10 @@ importers: specifier: ^1.7.10 version: 1.8.0 '@certd/basic': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/basic '@certd/pipeline': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/pipeline '@kubernetes/client-node': specifier: 0.21.0 @@ -771,19 +771,19 @@ importers: packages/pro/commercial-core: dependencies: '@certd/basic': - specifier: ^1.32.0 + specifier: ^1.33.4 version: link:../../core/basic '@certd/lib-server': - specifier: ^1.32.0 + specifier: ^1.33.4 version: link:../../libs/lib-server '@certd/pipeline': - specifier: ^1.32.0 + specifier: ^1.33.4 version: link:../../core/pipeline '@certd/plugin-plus': - specifier: ^1.32.0 + specifier: ^1.33.4 version: link:../plugin-plus '@certd/plus-core': - specifier: ^1.32.0 + specifier: ^1.33.4 version: link:../plus-core '@midwayjs/core': specifier: ~3.20.3 @@ -868,22 +868,22 @@ importers: specifier: ^1.0.2 version: 1.0.2 '@certd/basic': - specifier: ^1.32.0 + specifier: ^1.33.4 version: link:../../core/basic '@certd/lib-k8s': - specifier: ^1.32.0 + specifier: ^1.33.4 version: link:../../libs/lib-k8s '@certd/pipeline': - specifier: ^1.32.0 + specifier: ^1.33.4 version: link:../../core/pipeline '@certd/plugin-cert': - specifier: ^1.32.0 + specifier: ^1.33.4 version: link:../../plugins/plugin-cert '@certd/plugin-lib': - specifier: ^1.32.0 + specifier: ^1.33.4 version: link:../../plugins/plugin-lib '@certd/plus-core': - specifier: ^1.32.0 + specifier: ^1.33.4 version: link:../plus-core ali-oss: specifier: ^6.21.0 @@ -980,7 +980,7 @@ importers: packages/pro/plus-core: dependencies: '@certd/basic': - specifier: ^1.32.0 + specifier: ^1.33.4 version: link:../../core/basic dayjs: specifier: ^1.11.7 @@ -1270,10 +1270,10 @@ importers: version: 0.1.3(zod@3.24.2) devDependencies: '@certd/lib-iframe': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../libs/lib-iframe '@certd/pipeline': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/pipeline '@rollup/plugin-commonjs': specifier: ^25.0.7 @@ -1453,44 +1453,44 @@ importers: specifier: ^3.705.0 version: 3.758.0(aws-crt@1.25.3) '@certd/acme-client': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/acme-client '@certd/basic': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/basic '@certd/commercial-core': - specifier: ^1.33.2 - version: 1.33.2(better-sqlite3@11.8.1)(encoding@0.1.13)(mysql2@3.14.0)(pg@8.13.3)(reflect-metadata@0.2.2)(ts-node@10.9.2(@types/node@18.19.80)(typescript@5.8.2)) + specifier: ^1.33.4 + version: link:../../pro/commercial-core '@certd/jdcloud': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../libs/lib-jdcloud '@certd/lib-huawei': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../libs/lib-huawei '@certd/lib-k8s': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../libs/lib-k8s '@certd/lib-server': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../libs/lib-server '@certd/midway-flyway-js': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../libs/midway-flyway-js '@certd/pipeline': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../core/pipeline '@certd/plugin-cert': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../plugins/plugin-cert '@certd/plugin-lib': - specifier: ^1.33.2 + specifier: ^1.33.4 version: link:../../plugins/plugin-lib '@certd/plugin-plus': - specifier: ^1.33.2 - version: 1.33.2(encoding@0.1.13) + specifier: ^1.33.4 + version: link:../../pro/plugin-plus '@certd/plus-core': - specifier: ^1.33.2 - version: 1.33.2 + specifier: ^1.33.4 + version: link:../../pro/plus-core '@corsinvest/cv4pve-api-javascript': specifier: ^8.3.0 version: 8.3.0 @@ -1629,6 +1629,9 @@ importers: nodemailer: specifier: ^6.9.16 version: 6.10.0 + otplib: + specifier: ^12.0.1 + version: 12.0.1 pg: specifier: ^8.12.0 version: 8.13.3 @@ -1638,6 +1641,9 @@ importers: qiniu: specifier: ^7.12.0 version: 7.14.0 + qrcode: + specifier: ^1.5.4 + version: 1.5.4 qs: specifier: ^6.13.1 version: 6.14.0 @@ -2620,15 +2626,6 @@ packages: '@better-scroll/zoom@2.5.1': resolution: {integrity: sha512-aGvFY5ooeZWS4RcxQLD+pGLpQHQxpPy0sMZV3yadcd2QK53PK9gS4Dp+BYfRv8lZ4/P2LoNEhr6Wq1DN6+uPlA==} - '@certd/commercial-core@1.33.2': - resolution: {integrity: sha512-LTRvwRAkMEU+knG+/eA8QbyK3EE2Z2eyn4763ILadCY/qHLAWqxg7NUD+fwsuAoByvsr3l5qLPPOF73p5s1iEA==} - - '@certd/plugin-plus@1.33.2': - resolution: {integrity: sha512-x8qdJ1qtYfqVNBQ3uWJuFVYUHHnteoaH/3vnYKjgAnEAcosruZAz8h5RwwOjDhR+Vsdda/sSRdjlTCVDLidHZg==} - - '@certd/plus-core@1.33.2': - resolution: {integrity: sha512-CsD+/P3Ycne3KzxrZAkFXGpCO9ZQNY4p28WAA2XfKQ6sLIYLuuDBP18V/E7EygfJEZ/c9KJWMkYgx/4wGGvb6w==} - '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} @@ -3787,6 +3784,21 @@ packages: '@one-ini/wasm@0.1.1': resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + '@otplib/core@12.0.1': + resolution: {integrity: sha512-4sGntwbA/AC+SbPhbsziRiD+jNDdIzsZ3JUyfZwjtKyc/wufl1pnSIaG4Uqx8ymPagujub0o92kgBnB89cuAMA==} + + '@otplib/plugin-crypto@12.0.1': + resolution: {integrity: sha512-qPuhN3QrT7ZZLcLCyKOSNhuijUi9G5guMRVrxq63r9YNOxxQjPm59gVxLM+7xGnHnM6cimY57tuKsjK7y9LM1g==} + + '@otplib/plugin-thirty-two@12.0.1': + resolution: {integrity: sha512-MtT+uqRso909UkbrrYpJ6XFjj9D+x2Py7KjTO9JDPhL0bJUYVu5kFP4TFZW4NFAywrAtFRxOVY261u0qwb93gA==} + + '@otplib/preset-default@12.0.1': + resolution: {integrity: sha512-xf1v9oOJRyXfluBhMdpOkr+bsE+Irt+0D5uHtvg6x1eosfmHCsCC6ej/m7FXiWqdo0+ZUI6xSKDhJwc8yfiOPQ==} + + '@otplib/preset-v11@12.0.1': + resolution: {integrity: sha512-9hSetMI7ECqbFiKICrNa4w70deTUfArtwXykPUvSHWOdzOlfa9ajglu7mNCntlvxycTiOAXkQGwjQCzzDEMRMg==} + '@panva/asn1.js@1.0.0': resolution: {integrity: sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==} engines: {node: '>=10.13.0'} @@ -9899,6 +9911,9 @@ packages: engines: {node: '>=0.10.0'} hasBin: true + otplib@12.0.1: + resolution: {integrity: sha512-xDGvUOQjop7RDgxTQ+o4pOol0/3xSZzawTiPKRrHnQWAy0WjhNs/5HdIDJCrqC4MBynmjXgULc6YfioaxZeFgg==} + output-file-sync@1.1.2: resolution: {integrity: sha512-uQLlclru4xpCi+tfs80l3QF24KL81X57ELNMy7W/dox+JTtxUf1bLyQ8968fFCmSqqbokjW0kn+WBIlO+rSkNg==} @@ -11985,6 +12000,10 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + thirty-two@1.0.2: + resolution: {integrity: sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==} + engines: {node: '>=0.2.6'} + throttle-debounce@5.0.2: resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} engines: {node: '>=12.22'} @@ -14803,75 +14822,6 @@ snapshots: dependencies: '@better-scroll/core': 2.5.1 - '@certd/commercial-core@1.33.2(better-sqlite3@11.8.1)(encoding@0.1.13)(mysql2@3.14.0)(pg@8.13.3)(reflect-metadata@0.2.2)(ts-node@10.9.2(@types/node@18.19.80)(typescript@5.8.2))': - dependencies: - '@certd/basic': link:packages/core/basic - '@certd/lib-server': link:packages/libs/lib-server - '@certd/pipeline': link:packages/core/pipeline - '@certd/plugin-plus': 1.33.2(encoding@0.1.13) - '@certd/plus-core': 1.33.2 - '@midwayjs/core': 3.20.3 - '@midwayjs/koa': 3.20.3 - '@midwayjs/logger': 3.4.2 - '@midwayjs/typeorm': 3.20.3 - alipay-sdk: 4.13.0 - dayjs: 1.11.13 - typeorm: 0.3.21(better-sqlite3@11.8.1)(mysql2@3.14.0)(pg@8.13.3)(reflect-metadata@0.2.2)(ts-node@10.9.2(@types/node@18.19.80)(typescript@5.8.2)) - wechatpay-node-v3: 2.2.1 - transitivePeerDependencies: - - '@google-cloud/spanner' - - '@sap/hana-client' - - better-sqlite3 - - encoding - - hdb-pool - - ioredis - - mongodb - - mssql - - mysql2 - - oracledb - - pg - - pg-native - - pg-query-stream - - proxy-agent - - redis - - reflect-metadata - - sql.js - - sqlite3 - - supports-color - - ts-node - - typeorm-aurora-data-api-driver - - '@certd/plugin-plus@1.33.2(encoding@0.1.13)': - dependencies: - '@alicloud/pop-core': 1.8.0 - '@baiducloud/sdk': 1.0.2 - '@certd/basic': link:packages/core/basic - '@certd/lib-k8s': link:packages/libs/lib-k8s - '@certd/pipeline': link:packages/core/pipeline - '@certd/plugin-cert': link:packages/plugins/plugin-cert - '@certd/plugin-lib': link:packages/plugins/plugin-lib - '@certd/plus-core': 1.33.2 - ali-oss: 6.22.0 - baidu-aip-sdk: 4.16.16 - basic-ftp: 5.0.5 - cos-nodejs-sdk-v5: 2.14.6 - crypto-js: 4.2.0 - dayjs: 1.11.13 - form-data: 4.0.2 - https-proxy-agent: 7.0.6 - jsencrypt: 3.3.2 - qiniu: 7.14.0 - tencentcloud-sdk-nodejs: 4.0.1045(encoding@0.1.13) - transitivePeerDependencies: - - encoding - - proxy-agent - - supports-color - - '@certd/plus-core@1.33.2': - dependencies: - '@certd/basic': link:packages/core/basic - dayjs: 1.11.13 - '@colors/colors@1.5.0': optional: true @@ -16306,6 +16256,29 @@ snapshots: '@one-ini/wasm@0.1.1': {} + '@otplib/core@12.0.1': {} + + '@otplib/plugin-crypto@12.0.1': + dependencies: + '@otplib/core': 12.0.1 + + '@otplib/plugin-thirty-two@12.0.1': + dependencies: + '@otplib/core': 12.0.1 + thirty-two: 1.0.2 + + '@otplib/preset-default@12.0.1': + dependencies: + '@otplib/core': 12.0.1 + '@otplib/plugin-crypto': 12.0.1 + '@otplib/plugin-thirty-two': 12.0.1 + + '@otplib/preset-v11@12.0.1': + dependencies: + '@otplib/core': 12.0.1 + '@otplib/plugin-crypto': 12.0.1 + '@otplib/plugin-thirty-two': 12.0.1 + '@panva/asn1.js@1.0.0': {} '@peculiar/asn1-cms@2.3.15': @@ -20700,13 +20673,13 @@ snapshots: resolve: 1.22.10 semver: 6.3.1 - eslint-plugin-prettier@3.4.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@7.32.0)(prettier@2.8.8): + eslint-plugin-prettier@3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8): dependencies: eslint: 7.32.0 prettier: 2.8.8 prettier-linter-helpers: 1.0.0 optionalDependencies: - eslint-config-prettier: 8.10.0(eslint@8.57.0) + eslint-config-prettier: 8.10.0(eslint@7.32.0) eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8): dependencies: @@ -23420,7 +23393,7 @@ snapshots: eslint: 7.32.0 eslint-config-prettier: 8.10.0(eslint@7.32.0) eslint-plugin-node: 11.1.0(eslint@7.32.0) - eslint-plugin-prettier: 3.4.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@7.32.0)(prettier@2.8.8) + eslint-plugin-prettier: 3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8) execa: 5.1.1 inquirer: 7.3.3 json5: 2.2.3 @@ -23853,6 +23826,12 @@ snapshots: dependencies: minimist: 1.2.8 + otplib@12.0.1: + dependencies: + '@otplib/core': 12.0.1 + '@otplib/preset-default': 12.0.1 + '@otplib/preset-v11': 12.0.1 + output-file-sync@1.1.2: dependencies: graceful-fs: 4.2.11 @@ -26255,6 +26234,8 @@ snapshots: dependencies: any-promise: 1.3.0 + thirty-two@1.0.2: {} + throttle-debounce@5.0.2: {} through2@2.0.5: