mirror of
https://github.com/certd/certd.git
synced 2026-04-14 04:20:52 +08:00
Compare commits
186 Commits
v1.35.0
...
v2-dev-aut
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56a36aa595 | ||
|
|
0b3158fdd5 | ||
|
|
896cd950e9 | ||
|
|
af5e1b805f | ||
|
|
3f9943270c | ||
|
|
785bee2b39 | ||
|
|
4b335db31c | ||
|
|
4bef527ebb | ||
|
|
8273031d7e | ||
|
|
24d3096752 | ||
|
|
9a3754fbf8 | ||
|
|
c2a95a13fe | ||
|
|
b46466ac96 | ||
|
|
06991ddb17 | ||
|
|
4b3f4a868a | ||
|
|
014eff3534 | ||
|
|
c01b7ddb59 | ||
|
|
0ff700849f | ||
|
|
5c695dea20 | ||
|
|
c7ee4ca4db | ||
|
|
c3da026b33 | ||
|
|
98da4e1791 | ||
|
|
8626b6d9f2 | ||
|
|
80c5331a5d | ||
|
|
39dc5c8160 | ||
|
|
f3002e4fb6 | ||
|
|
c451823c2b | ||
|
|
b37cffd704 | ||
|
|
2af91dbf2a | ||
|
|
f2551318fc | ||
|
|
22eb84f944 | ||
|
|
1ece0915f1 | ||
|
|
87853a2015 | ||
|
|
46a1b74799 | ||
|
|
0f6e7e5eab | ||
|
|
5dfa9615d2 | ||
|
|
1bde777bee | ||
|
|
fa4f5df3e7 | ||
|
|
8a3c3810e0 | ||
|
|
144532530a | ||
|
|
0f1129e19b | ||
|
|
1f74580f15 | ||
|
|
f93ba9970c | ||
|
|
f87a3d0892 | ||
|
|
c661ad67d0 | ||
|
|
ce4dc9e3fa | ||
|
|
3d2c6e6032 | ||
|
|
6000a0cfe3 | ||
|
|
b80c60997a | ||
|
|
35e45f0df1 | ||
|
|
e65f5b9f78 | ||
|
|
5969f71e67 | ||
|
|
b1307863eb | ||
|
|
9d0abe993b | ||
|
|
c53bb7cf67 | ||
|
|
0cea26c628 | ||
|
|
610c919c72 | ||
|
|
2c35f94f7c | ||
|
|
cd9a3870b3 | ||
|
|
e11373f23a | ||
|
|
f591635fc1 | ||
|
|
474b57ca61 | ||
|
|
8671887abc | ||
|
|
8274d1baa5 | ||
|
|
bde601bfff | ||
|
|
a2e0951042 | ||
|
|
3c9a8a38dd | ||
|
|
4c067fd39f | ||
|
|
5c251ee774 | ||
|
|
ddda691552 | ||
|
|
ba73090d53 | ||
|
|
a080b606ab | ||
|
|
7c0f43c8a3 | ||
|
|
4fad1aee6b | ||
|
|
19aec5bc8d | ||
|
|
33ee60736c | ||
|
|
c1bccb970f | ||
|
|
481cc029fa | ||
|
|
bdaf58a3c4 | ||
|
|
0f64671dc0 | ||
|
|
60f055f293 | ||
|
|
c67a9215e3 | ||
|
|
a0e9df6d6d | ||
|
|
8341749c04 | ||
|
|
66d1886663 | ||
|
|
710e1fc278 | ||
|
|
4cf98584da | ||
|
|
3fb3cee423 | ||
|
|
2d1504a057 | ||
|
|
4fcfd089d8 | ||
|
|
04422a4637 | ||
|
|
37e6548246 | ||
|
|
a761989f3e | ||
|
|
acaa8b1731 | ||
|
|
082f47663d | ||
|
|
92f42154d5 | ||
|
|
fc1084ce33 | ||
|
|
adc3ab7e0a | ||
|
|
dcc8c56969 | ||
|
|
0b3472d227 | ||
|
|
b50121ad0b | ||
|
|
dfddfc3e06 | ||
|
|
34ec6210c6 | ||
|
|
daaef316e9 | ||
|
|
cdac12bb2f | ||
|
|
3ab99647aa | ||
|
|
529482a83e | ||
|
|
29906ec057 | ||
|
|
9296ba7492 | ||
|
|
821c6d807d | ||
|
|
991b741cbe | ||
|
|
2559f0e822 | ||
|
|
8bb1ed3e95 | ||
|
|
56ba3fcb92 | ||
|
|
e99a20a120 | ||
|
|
f1a25b21a6 | ||
|
|
cf9595ce58 | ||
|
|
7feece597a | ||
|
|
fa16c782ca | ||
|
|
a03d0b6a4a | ||
|
|
dff76b8912 | ||
|
|
cffea9a9bc | ||
|
|
43fee42198 | ||
|
|
5cd3968929 | ||
|
|
65dcae79f8 | ||
|
|
2b3b75a4a5 | ||
|
|
26b395110c | ||
|
|
e11b3becfd | ||
|
|
73fa937f5c | ||
|
|
6ebe2e54ac | ||
|
|
fb29a11cc9 | ||
|
|
a9e06cbf92 | ||
|
|
93017c044d | ||
|
|
c223ddbb9a | ||
|
|
f00aeacb8b | ||
|
|
5b49071d6b | ||
|
|
17053a882b | ||
|
|
5e723d31a4 | ||
|
|
3283bd8b75 | ||
|
|
770d3c0015 | ||
|
|
d15dfafd5d | ||
|
|
545c13d55c | ||
|
|
e2099ac9ca | ||
|
|
c937583a50 | ||
|
|
43c7a19849 | ||
|
|
83543487e7 | ||
|
|
434b259525 | ||
|
|
add8efaba8 | ||
|
|
12ed79ca60 | ||
|
|
1e863382d3 | ||
|
|
bad3504d4a | ||
|
|
d94f207162 | ||
|
|
2c4b7781a4 | ||
|
|
4574c6ff07 | ||
|
|
7b5043e87b | ||
|
|
a06f3ac5da | ||
|
|
721346a40a | ||
|
|
f252871fb8 | ||
|
|
107196122c | ||
|
|
563c02d8da | ||
|
|
765934970a | ||
|
|
9cbdfda829 | ||
|
|
c1fbc8cd68 | ||
|
|
a92107cc47 | ||
|
|
3e84e116e8 | ||
|
|
7c0cdd169e | ||
|
|
424fd96615 | ||
|
|
ebfcea88da | ||
|
|
3c7eb2f5e2 | ||
|
|
936167972f | ||
|
|
7f6070c960 | ||
|
|
0aea9c129c | ||
|
|
d20fb7daa8 | ||
|
|
a619f8a2fe | ||
|
|
0acb858d7b | ||
|
|
e459be76fe | ||
|
|
c4c59ccc75 | ||
|
|
c820315409 | ||
|
|
2a19b61b7a | ||
|
|
e1cf64ae16 | ||
|
|
d3c2f8eb43 | ||
|
|
a00453c83a | ||
|
|
2eb0e54909 | ||
|
|
ac87bc57e9 | ||
|
|
2b8ea857f0 | ||
|
|
11c52114b2 |
138
CHANGELOG.md
138
CHANGELOG.md
@@ -3,6 +3,144 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 某些插件找不到的bug ([4b3f4a8](https://github.com/certd/certd/commit/4b3f4a868a8b0800c5c59de9d0f47bddc079e7b3))
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复查看证书对话框翻译错误的bug ([8626b6d](https://github.com/certd/certd/commit/8626b6d9f235c511766f2ae98e0a37f6cebb621c))
|
||||||
|
* 修复translation后分组编辑打不开的bug ([46a1b74](https://github.com/certd/certd/commit/46a1b7479923d2feb2dece202a5932b99981b2cd))
|
||||||
|
* 执行windows nginx命令时,改为return code判断是否执行成功 ([b37cffd](https://github.com/certd/certd/commit/b37cffd704cd08b8bdd68a6e284706eabe59e78d))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化证书进度条颜色 ([2af91db](https://github.com/certd/certd/commit/2af91dbf2ae36a4ed17c6788bc2a2a79a3bb29f8))
|
||||||
|
* 站点证书即将过期通知标题颜色优化为红色 ([80c5331](https://github.com/certd/certd/commit/80c5331a5d4c320323d9b9b800e4ea3b72577b33))
|
||||||
|
* 支持部署到阿里云vod ([98da4e1](https://github.com/certd/certd/commit/98da4e1791ed8bb21daf2a9914fda875d14633c9))
|
||||||
|
* 支持部署证书到网宿CDN ([c3da026](https://github.com/certd/certd/commit/c3da026b33106f5195959825a68cadbe49efef00))
|
||||||
|
* 重置管理员密码同时可以清除管理员的2FA设置 ([1ece091](https://github.com/certd/certd/commit/1ece0915f172d5f8b8adb866434e7efcc5c8c46d))
|
||||||
|
* output-selector from参数支持更丰富的过滤规则 ([87853a2](https://github.com/certd/certd/commit/87853a201535f3bfe8505c40f8f5229d82ffcc73))
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复开放接口添加按钮文本显示问题 ([f93ba99](https://github.com/certd/certd/commit/f93ba9970c12680f38eba2a7abd4b72cf3f5b6a6))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化部署到腾讯TKE插件,支持Opaque类型选择,优化填写说明 ([1445325](https://github.com/certd/certd/commit/144532530a865b634e68539e4888e26f52f73492))
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复notification编辑按钮无法打开对话框的bug ([0cea26c](https://github.com/certd/certd/commit/0cea26c6287f52adf273b4a525c37bea8555c68c))
|
||||||
|
* 优化更新飞牛os证书有效期,修复某些情况下部署证书后飞牛无法访问https的bug ([610c919](https://github.com/certd/certd/commit/610c919c72037becc0ed326f5d5b18c963dfcb3a))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 证书检查支持自定义dns服务器 ([c53bb7c](https://github.com/certd/certd/commit/c53bb7cf677faa32729709ae0c10359db5194d7a))
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复通知和触发器无法编辑的bug ([a2e0951](https://github.com/certd/certd/commit/a2e09510426680eb425c0d7ad337f39d3f052054))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持部署到七牛云DCDN ([bde601b](https://github.com/certd/certd/commit/bde601bfffb4f7345d97e1e3b064520816d31555))
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 支持自定义证书生成插件 ([481cc02](https://github.com/certd/certd/commit/481cc029fafaf280aa844cd3ca30f4653ec35d55))
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* 支持模版创建流水线 ([2559f0e](https://github.com/certd/certd/commit/2559f0e822db095d1d26a7f1d517622dce22a5c2))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 阿里云waf cname站点选择支持翻页及域名查询 ([4cf9858](https://github.com/certd/certd/commit/4cf98584dacc5999752732f136246647a2f1f07d))
|
||||||
|
* 部署到ssh主机命令支持前置命令 ([991b741](https://github.com/certd/certd/commit/991b741cbe223b342f534157da63b71e81661f8e))
|
||||||
|
* 模版导入流水线 ([dcc8c56](https://github.com/certd/certd/commit/dcc8c569693432579709ce63656665a76bcf9a44))
|
||||||
|
* 添加用户资料编辑功能 ([7c0f43c](https://github.com/certd/certd/commit/7c0f43c8a3052f73afee3e93c9fcbc43c44ab690))
|
||||||
|
* 优化阿里云waf的日志信息 ([821c6d8](https://github.com/certd/certd/commit/821c6d807d4b3cc5092d09a6282b8cbafb9e7c9f))
|
||||||
|
* 优化中英文翻译与切换 ([acaa8b1](https://github.com/certd/certd/commit/acaa8b173183b4423584ee070e6e332e0ac0eb2d))
|
||||||
|
* 站点IP监控前先同步一下IP ([a080b60](https://github.com/certd/certd/commit/a080b606ab6e289d96b17ef7d2879b4603f889ba))
|
||||||
|
* 支持选择运行策略设置 ([60f055f](https://github.com/certd/certd/commit/60f055f293ce237c21cd9050333dad9609eceac1))
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 腾讯云授权支持设置是否国际站,部署到EO插件支持国际站 ([5cd3968](https://github.com/certd/certd/commit/5cd3968929acef333cf30d3b20cf21cea6c82c5f))
|
||||||
|
* 修复邮箱包含.号校验失败的bug ([65dcae7](https://github.com/certd/certd/commit/65dcae79f8faa7a6cb425e10a0fdb6758b0719f3))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 首次打开任务日志查看页面,自动滚动到底部 ([43fee42](https://github.com/certd/certd/commit/43fee42198e8697185b427b1fa3eb79409603393))
|
||||||
|
* 支持批量修改通知和定时 ([e11b3be](https://github.com/certd/certd/commit/e11b3becfd4abe6547e84d09adc38ebd6e1c4b87))
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持s3 access做测试 ([f00aeac](https://github.com/certd/certd/commit/f00aeacb8b5c81f0bafa4c1b76723dec2b6b7784))
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复消息内容存在()<>等括号情况下无法发送tg通知的bug ([c937583](https://github.com/certd/certd/commit/c937583a50d8513d76adead3648f83eee2fcc6f9))
|
||||||
|
* 修复重试次数设置无效的bug ([e2099ac](https://github.com/certd/certd/commit/e2099ac9ca344bc70bfa4219002e9138708973ae))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 授权列表类型颜色优化 ([1e86338](https://github.com/certd/certd/commit/1e863382d3d1a8cc95a1abf51e75bf6eaea3244f))
|
||||||
|
* 支持雨云dns解析 ([8354348](https://github.com/certd/certd/commit/83543487e7418683bd79cfe3b9e0d792bdb977f7))
|
||||||
|
* 支持雨云dns解析以及雨云证书更新 ([43c7a19](https://github.com/certd/certd/commit/43c7a1984926f5d4647760cc134bb0aede3a7b7a))
|
||||||
|
* github 版本检查支持执行脚本 ([bad3504](https://github.com/certd/certd/commit/bad3504d4a15e6989b967b66aa9da8c6981f25bf))
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复阿里云新加坡clb无法部署证书的bug ([c1fbc8c](https://github.com/certd/certd/commit/c1fbc8cd68ae020ef342e4e92f4d9b4869ca1ead))
|
||||||
|
* 修复阿里云新加坡clb无法部署证书的bug ([3e84e11](https://github.com/certd/certd/commit/3e84e116e863b54c6b4d7db160af372dacc5857f))
|
||||||
|
* 修复检查github release 插件无法保存最后版本的bug ([a92107c](https://github.com/certd/certd/commit/a92107cc47133883b099d5228b06373e84c8bb50))
|
||||||
|
* 修复站点监控定时器多次添加的bug ([9361679](https://github.com/certd/certd/commit/936167972fe83e519bc01a0dd961d9c0635d24ab))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 阿里云dns操作增加重试机制 ([424fd96](https://github.com/certd/certd/commit/424fd96615c05e949af8c837c261c1400bdffba2))
|
||||||
|
* 优化阿里云nlb支持部署扩展证书 ([9cbdfda](https://github.com/certd/certd/commit/9cbdfda829b231733d54c66c5024d46e6fc11af3))
|
||||||
|
* 子域名托管帮助链接优化为打开新窗口 ([7c0cdd1](https://github.com/certd/certd/commit/7c0cdd169e2f943e703e433677f2f437d4aa02ee))
|
||||||
|
* history增加触发类型显示 ([7f6070c](https://github.com/certd/certd/commit/7f6070c960ed7bf02add5ab36436de6573f2f1fa))
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 某些证书提供商的证书确实commonName导致无法转换证书的问题 ([ac87bc5](https://github.com/certd/certd/commit/ac87bc57e957ea4679707bfd38d6840e26319bed))
|
||||||
|
* 修复站点监控通知渠道设置无效的bug ([a00453c](https://github.com/certd/certd/commit/a00453c83a58114ce2873dd6e6aaf313f1ce0f87))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 修改 HTTPS 服务器监听地址 ([e1cf64a](https://github.com/certd/certd/commit/e1cf64ae16d4abfe4299ff16d5088c30cf3c6365))
|
||||||
|
* 优化流水线页面,增加下次执行时间、查看证书显示 ([c820315](https://github.com/certd/certd/commit/c8203154094fae3d17198747f49f5f41ddf29a4e))
|
||||||
|
* 站点证书监控支持定时设置,重试次数设置 ([d3c2f8e](https://github.com/certd/certd/commit/d3c2f8eb436e670772d14a54acd6b541c5aa3978))
|
||||||
|
* 证书申请支持letencrypt profile选项 ([2eb0e54](https://github.com/certd/certd/commit/2eb0e54909d8ad36708e07c12fd598998159bc43))
|
||||||
|
* aliyun alb支持部署扩展证书 ([2a19b61](https://github.com/certd/certd/commit/2a19b61b7a78620c06396c2cc37cc77d738b6d12))
|
||||||
|
|
||||||
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
57
README.md
57
README.md
@@ -1,9 +1,12 @@
|
|||||||
# Certd
|
# Certd
|
||||||
|
|
||||||
Certd 是一个免费全自动申请和自动部署更新SSL证书的管理系统。
|
[English](./README_en.md) | [中文](./README.md)
|
||||||
后缀d取自linux守护进程的命名风格,意为证书守护进程。
|
|
||||||
|
|
||||||
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具
|
Certd® 是一个免费的全自动证书管理系统,让你的网站证书永不过期。
|
||||||
|
后缀d取自linux守护进程的命名风格,意为证书守护进程
|
||||||
|
|
||||||
|
|
||||||
|
>首创流水线申请部署证书模式,已被多个项目“借鉴”,被抄也是一种成功。
|
||||||
|
|
||||||
> 关于证书续期:
|
> 关于证书续期:
|
||||||
>* 实际上没有办法不改变证书文件本身情况下直接续期或者续签。
|
>* 实际上没有办法不改变证书文件本身情况下直接续期或者续签。
|
||||||
@@ -13,6 +16,7 @@ Certd 是一个免费全自动申请和自动部署更新SSL证书的管理系
|
|||||||
|
|
||||||
> 流水线数量现已调整为无限制,欢迎大家使用
|
> 流水线数量现已调整为无限制,欢迎大家使用
|
||||||
|
|
||||||
|
|
||||||
## 一、特性
|
## 一、特性
|
||||||
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
||||||
|
|
||||||
@@ -20,21 +24,19 @@ Certd 是一个免费全自动申请和自动部署更新SSL证书的管理系
|
|||||||
* 全自动部署更新证书(目前支持部署到主机、阿里云、腾讯云等70+部署插件)
|
* 全自动部署更新证书(目前支持部署到主机、阿里云、腾讯云等70+部署插件)
|
||||||
* 支持通配符域名/泛域名,支持多个域名打到一个证书上,支持pem、pfx、der、jks等多种证书格式
|
* 支持通配符域名/泛域名,支持多个域名打到一个证书上,支持pem、pfx、der、jks等多种证书格式
|
||||||
* 邮件通知、webhook通知、企微、钉钉、飞书、anpush等多种通知方式
|
* 邮件通知、webhook通知、企微、钉钉、飞书、anpush等多种通知方式
|
||||||
* 私有化部署,数据保存本地,安装升级非常简单快捷
|
* 私有化部署,数据保存本地,安装简单快捷,镜像由Github Actions构建,过程公开透明
|
||||||
* 镜像由Github Actions构建,过程公开透明
|
|
||||||
* 授权加密,站点隐藏,2FA,密码防爆破等多重安全保障
|
* 授权加密,站点隐藏,2FA,密码防爆破等多重安全保障
|
||||||
* 支持SQLite,PostgreSQL、MySQL多种数据库
|
* 支持SQLite,PostgreSQL、MySQL多种数据库
|
||||||
* 开放接口支持
|
* 开放接口支持
|
||||||
* 站点证书监控
|
* 站点证书监控
|
||||||
* 多用户管理
|
* 多用户管理
|
||||||
|
* 多语言支持(中英双语切换)
|
||||||
|
* 各版本向下兼容,一键无忧升级
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 二、在线体验
|
## 二、在线体验
|
||||||
|
|
||||||
官方Demo地址,自助注册后体验
|
官方Demo地址,自助注册后体验
|
||||||
@@ -82,10 +84,12 @@ https://certd.handfree.work/
|
|||||||
|
|
||||||
您可以根据实际情况从如下方式中选择一种方式进行私有化部署:
|
您可以根据实际情况从如下方式中选择一种方式进行私有化部署:
|
||||||
|
|
||||||
1. [宝塔面板方式部署 推荐](https://certd.docmirror.cn/guide/install/docker/)
|
1. 【推荐】[Docker方式部署 ](https://certd.docmirror.cn/guide/install/docker/)
|
||||||
2. [1Panel面板方式部署 推荐](https://certd.docmirror.cn/guide/install/1panel/)
|
2. 【推荐】[宝塔面板方式部署 ](https://certd.docmirror.cn/guide/install/docker/)
|
||||||
3. [Docker方式部署 推荐](https://certd.docmirror.cn/guide/install/docker/)
|
3. 【推荐】[1Panel面板方式部署](https://certd.docmirror.cn/guide/install/1panel/)
|
||||||
4. [源码方式部署 不建议](https://certd.docmirror.cn/guide/install/source/)
|
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镜像说明:
|
#### Docker镜像说明:
|
||||||
* 国内镜像地址:
|
* 国内镜像地址:
|
||||||
@@ -113,7 +117,17 @@ https://certd.handfree.work/
|
|||||||
> * [更多安全生产建议点我](https://certd.docmirror.cn/guide/feature/safe/)
|
> * [更多安全生产建议点我](https://certd.docmirror.cn/guide/feature/safe/)
|
||||||
|
|
||||||
|
|
||||||
## 五、更多帮助
|
## 五、生态
|
||||||
|
|
||||||
|
### 1. 客户端工具 SSL-Assistant
|
||||||
|
`SSL Assistant` 是一个运行于主机上的证书部署管理助手客户端。
|
||||||
|
支持自动扫描主机`Nginx`配置,然后从`Certd`拉取证书并部署。
|
||||||
|
在不想暴露ssh主机密码情况下,该工具非常好用。
|
||||||
|
|
||||||
|
开源地址: https://github.com/Youngxj/SSL-Assistant
|
||||||
|
|
||||||
|
|
||||||
|
## 六、更多帮助
|
||||||
请访问官方文档:[https://certd.docmirror.cn/](https://certd.docmirror.cn/guide/)
|
请访问官方文档:[https://certd.docmirror.cn/](https://certd.docmirror.cn/guide/)
|
||||||
|
|
||||||
* 升级方法:[升级方法](https://certd.docmirror.cn/guide/install/upgrade/)
|
* 升级方法:[升级方法](https://certd.docmirror.cn/guide/install/upgrade/)
|
||||||
@@ -123,7 +137,7 @@ https://certd.handfree.work/
|
|||||||
* 更新日志:[CHANGELOG](./CHANGELOG.md)
|
* 更新日志:[CHANGELOG](./CHANGELOG.md)
|
||||||
|
|
||||||
|
|
||||||
## 六、联系作者
|
## 七、联系作者
|
||||||
如有疑问,欢迎加入群聊(请备注certd)
|
如有疑问,欢迎加入群聊(请备注certd)
|
||||||
|
|
||||||
| 加群 | 微信群 | QQ群 |
|
| 加群 | 微信群 | QQ群 |
|
||||||
@@ -137,7 +151,7 @@ https://certd.handfree.work/
|
|||||||
| 二维码 | <img height="230" src="./docs/guide/contact/images/me.png"> |
|
| 二维码 | <img height="230" src="./docs/guide/contact/images/me.png"> |
|
||||||
|
|
||||||
|
|
||||||
## 七、捐赠
|
## 八、捐赠
|
||||||
************************
|
************************
|
||||||
支持开源,为爱发电,我已入驻爱发电
|
支持开源,为爱发电,我已入驻爱发电
|
||||||
https://afdian.com/a/greper
|
https://afdian.com/a/greper
|
||||||
@@ -161,7 +175,7 @@ https://afdian.com/a/greper
|
|||||||
|
|
||||||
************************
|
************************
|
||||||
|
|
||||||
## 八、贡献代码
|
## 九、贡献代码
|
||||||
|
|
||||||
1. 本地开发请参考 [贡献插件向导](https://certd.docmirror.cn/guide/development/)
|
1. 本地开发请参考 [贡献插件向导](https://certd.docmirror.cn/guide/development/)
|
||||||
2. 作为贡献者,代表您同意您贡献的代码如下许可:
|
2. 作为贡献者,代表您同意您贡献的代码如下许可:
|
||||||
@@ -174,17 +188,16 @@ https://afdian.com/a/greper
|
|||||||
<img src="https://contrib.rocks/image?repo=certd/certd" />
|
<img src="https://contrib.rocks/image?repo=certd/certd" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
## 九、 开源许可
|
## 十、 开源许可
|
||||||
* 本项目遵循 GNU Affero General Public License(AGPL)开源协议。
|
* 本项目遵循 GNU Affero General Public License(AGPL)开源协议。
|
||||||
* 允许个人和公司内部自由使用、复制、修改和分发本项目,未获得商业授权情况下禁止任何形式的商业用途
|
* 允许个人和公司内部自由使用、复制、修改和分发本项目,未获得商业授权情况下禁止任何形式的商业用途
|
||||||
* 未获得商业授权情况下,禁止任何对logo、版权信息及授权许可相关代码的修改。
|
* 未获得商业授权情况下,禁止任何对logo、版权信息及授权许可相关代码的修改。
|
||||||
* 如需商业授权,请联系作者。
|
* 如需商业授权,请联系作者。
|
||||||
|
|
||||||
|
|
||||||
## 十、我的其他项目(求Star)
|
## 十一、我的其他项目(求Star)
|
||||||
|
|
||||||
| 项目名称 | stars | 项目描述 |
|
| 项目名称 | stars | 项目描述 |
|
||||||
|---------------------------------------------------------|-------------------------------------------------------------------------------------------------------|-----------------------------------|
|
| --------- |--------- |----------- |
|
||||||
| [袖手AI](https://ai.handsfree.work/) | | 袖手GPT,国内可用,无需FQ,每日免费额度 |
|
|
||||||
| [fast-crud](https://gitee.com/fast-crud/fast-crud/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/fast-crud/fast-crud?logo=github"/> | 基于vue3的crud快速开发框架 |
|
| [fast-crud](https://gitee.com/fast-crud/fast-crud/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/fast-crud/fast-crud?logo=github"/> | 基于vue3的crud快速开发框架 |
|
||||||
| [dev-sidecar](https://github.com/docmirror/dev-sidecar/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/docmirror/dev-sidecar?logo=github"/> | 直连访问github工具,无需FQ,解决github无法访问的问题 |
|
| [dev-sidecar](https://github.com/docmirror/dev-sidecar/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/docmirror/dev-sidecar?logo=github"/> | 直连访问github工具,无需FQ,解决github无法访问的问题 |
|
||||||
|
|||||||
183
README_en.md
Normal file
183
README_en.md
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
# Certd
|
||||||
|
|
||||||
|
[English](./README_en.md) | [中文](./README.md)
|
||||||
|
|
||||||
|
Certd® is a free, fully automated certificate management system that ensures your website certificates never expire. The suffix 'd' is inspired by the naming convention of Linux daemons, representing a certificate daemon.
|
||||||
|
|
||||||
|
> We pioneered the pipeline-based certificate application and deployment model, which has been "referenced" by multiple projects. Being copied is also a form of success.
|
||||||
|
|
||||||
|
> Regarding certificate renewal:
|
||||||
|
>* In fact, it's impossible to renew or reissue a certificate without modifying the certificate file itself.
|
||||||
|
>* What we refer to as renewal is essentially applying for a new certificate following the full process and redeploying it.
|
||||||
|
>* Free certificates expire in 90 days, which may be shortened in the future. Therefore, automated deployment is essential.
|
||||||
|
|
||||||
|
> The number of pipelines is now unlimited. Welcome to use it.
|
||||||
|
|
||||||
|
## 1. Features
|
||||||
|
This project not only supports automated certificate application but also automated certificate deployment and updates, ensuring your certificates never expire.
|
||||||
|
|
||||||
|
* Fully automated certificate application (supports domains registered with all registrars and multiple domain verification methods such as DNS-01, HTTP-01, and CNAME proxy).
|
||||||
|
* Fully automated certificate deployment and updates (currently supports deployment to over 70 plugins, including hosts, Alibaba Cloud, Tencent Cloud, etc.).
|
||||||
|
* Supports wildcard domains/pan-domains, allows multiple domains in a single certificate, and supports various certificate formats such as pem, pfx, der, and jks.
|
||||||
|
* Multiple notification methods, including email, webhook, WeChat Work, DingTalk, Lark, and anpush.
|
||||||
|
* On-premises deployment, local data storage, simple and quick installation. Images are built by Github Actions, with a transparent process.
|
||||||
|
* Multiple security measures, including authorization encryption, site hiding, 2FA, and password brute-force protection.
|
||||||
|
* Supports multiple databases such as SQLite, PostgreSQL, and MySQL.
|
||||||
|
* Open API support.
|
||||||
|
* Site certificate monitoring.
|
||||||
|
* Multi-user management.
|
||||||
|
* Multi-language support (Chinese and English switching).
|
||||||
|
* Downward compatibility across all versions, with one-click worry-free upgrades.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 2. Online Experience
|
||||||
|
Visit the official demo site and register to experience it.
|
||||||
|
|
||||||
|
https://certd.handfree.work/
|
||||||
|
|
||||||
|
> Note: Data will be cleaned up irregularly, and scheduled tasks may be stopped. For production use, please deploy it yourself.
|
||||||
|
> The content contains sensitive information. Make sure to deploy it locally for production use.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 3. Usage Tutorial
|
||||||
|
Just 3 steps to ensure your certificates never expire.
|
||||||
|
|
||||||
|
### 1. Create a Certificate Pipeline
|
||||||
|

|
||||||
|
|
||||||
|
> After successful addition, you can directly run the pipeline to apply for a certificate.
|
||||||
|
|
||||||
|
### 2. Add a Deployment Task
|
||||||
|
Normally, we need to deploy certificates to applications. Certd supports a wide range of deployment plugins. You can choose based on your needs, such as deploying to Nginx, Alibaba Cloud, Tencent Cloud, K8S, CDN, Baota, 1Panel, etc.
|
||||||
|
|
||||||
|
Here's a demonstration of deploying certificates to a host's Nginx:
|
||||||
|

|
||||||
|
|
||||||
|
If the current deployment plugins don't meet your needs, you can also download them manually and deploy them yourself.
|
||||||
|

|
||||||
|
|
||||||
|
### 3. Run Scheduled Tasks
|
||||||
|

|
||||||
|
|
||||||
|
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
|
||||||
|
-------> [Click here to view detailed usage steps](./step.md) <--------
|
||||||
|
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
|
||||||
|
|
||||||
|
For more tutorials, please visit the official documentation [certd.docmirror.cn](https://certd.docmirror.cn/guide/).
|
||||||
|
|
||||||
|
## 4. On-Premises Deployment
|
||||||
|
Since certificates, authorization information, and other data are highly sensitive, please make sure to deploy them on-premises to ensure data security.
|
||||||
|
|
||||||
|
You can choose one of the following deployment methods based on your needs:
|
||||||
|
|
||||||
|
1. 【Recommended】[Docker Deployment](https://certd.docmirror.cn/guide/install/docker/)
|
||||||
|
2. 【Recommended】[BT Panel Deployment](https://certd.docmirror.cn/guide/install/docker/)
|
||||||
|
3. 【Recommended】[1Panel Deployment](https://certd.docmirror.cn/guide/install/1panel/)
|
||||||
|
4. 【Recommended】[Rainyun One-Click Deployment](https://app.rainyun.com/apps/rca/store/6646/?ref=NzExMDQ2_): Double your first recharge, only $2.2 per month.
|
||||||
|
[<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. 【Not Recommended】[Source Code Deployment](https://certd.docmirror.cn/guide/install/source/)
|
||||||
|
|
||||||
|
#### Docker Image Information:
|
||||||
|
* Domestic Image Addresses:
|
||||||
|
* `registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest`
|
||||||
|
* `registry.cn-shenzhen.aliyuncs.com/handsfree/certd:armv7`, `[version]-armv7`
|
||||||
|
* DockerHub Addresses:
|
||||||
|
* `https://hub.docker.com/r/greper/certd`
|
||||||
|
* `greper/certd:latest`
|
||||||
|
* `greper/certd:armv7`, `greper/certd:[version]-armv7`
|
||||||
|
* GitHub Packages Addresses:
|
||||||
|
* `ghcr.io/certd/certd:latest`
|
||||||
|
* `ghcr.io/certd/certd:armv7`, `ghcr.io/certd/certd:[version]-armv7`
|
||||||
|
|
||||||
|
* Images are built automatically by `Actions`, with a transparent process. Please use them with confidence.
|
||||||
|
* [Click here to view image build logs](https://github.com/certd/certd/actions/workflows/build-image.yml)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> Note:
|
||||||
|
> * The certificates, authorization information, and other data stored in this application are highly sensitive. Please take appropriate security measures.
|
||||||
|
> * Make sure to use the HTTPS protocol to access this application to avoid man-in-the-middle attacks.
|
||||||
|
> * Make sure to use a web application firewall to protect this application from attacks such as XSS and SQL injection.
|
||||||
|
> * Make sure to secure the server itself to prevent database leakage.
|
||||||
|
> * Make sure to back up your data to avoid data loss.
|
||||||
|
> * [Click here for more production safety suggestions](https://certd.docmirror.cn/guide/feature/safe/)
|
||||||
|
|
||||||
|
## 5. Ecosystem
|
||||||
|
|
||||||
|
### 1. Client Tool: SSL-Assistant
|
||||||
|
`SSL Assistant` is a certificate deployment and management assistant client that runs on hosts. It supports automatic scanning of the host's `Nginx` configuration and pulling certificates from `Certd` for deployment. This tool is very useful when you don't want to expose your SSH host password.
|
||||||
|
|
||||||
|
Open-source Address: https://github.com/Youngxj/SSL-Assistant
|
||||||
|
|
||||||
|
## 6. More Help
|
||||||
|
Please visit the official documentation: [https://certd.docmirror.cn/](https://certd.docmirror.cn/guide/).
|
||||||
|
|
||||||
|
* Upgrade Method: [Upgrade Guide](https://certd.docmirror.cn/guide/install/upgrade/)
|
||||||
|
* Common Issues: [Forgot Password](https://certd.docmirror.cn/guide/use/forgotpasswd/)
|
||||||
|
* Multi-Database: [Multi-Database Configuration](https://certd.docmirror.cn/guide/install/database/)
|
||||||
|
* Site Security: [Site Security Features](https://certd.docmirror.cn/guide/feature/safe/)
|
||||||
|
* Changelog: [CHANGELOG](./CHANGELOG.md)
|
||||||
|
|
||||||
|
## 7. Contact the Author
|
||||||
|
If you have any questions, feel free to join the group chat (please mention 'certd' in your message).
|
||||||
|
|
||||||
|
| Join Group | WeChat Group | QQ Group |
|
||||||
|
|---------|-------|-------|
|
||||||
|
| QR Code | <img height="230" src="./docs/guide/contact/images/wx.png"> | <img height="230" src="./docs/guide/contact/images/qq.png"> |
|
||||||
|
|
||||||
|
You can also add the author as a friend.
|
||||||
|
|
||||||
|
| Add Author as Friend | WeChat QQ |
|
||||||
|
|---------|-------|-------|
|
||||||
|
| QR Code | <img height="230" src="./docs/guide/contact/images/me.png"> |
|
||||||
|
|
||||||
|
## 8. Donation
|
||||||
|
************************
|
||||||
|
Support open-source projects and contribute with love. I've joined Afdian.
|
||||||
|
https://afdian.com/a/greper
|
||||||
|
|
||||||
|
Benefits of Contribution:
|
||||||
|
1. Join the exclusive contributor group and get one-on-one technical support from the author.
|
||||||
|
2. Your requests will be prioritized and implemented as professional edition features.
|
||||||
|
3. Receive a one-year professional edition activation code.
|
||||||
|
|
||||||
|
Comparison of Professional Edition Privileges:
|
||||||
|
|
||||||
|
| Feature | Free Edition | Professional Edition |
|
||||||
|
|---------|---------------------------------------|--------------------------------|
|
||||||
|
| Free Certificate Application | Unlimited for free | Unlimited for free |
|
||||||
|
| Number of Domains | Unlimited | Unlimited |
|
||||||
|
| Number of Certificate Pipelines | Unlimited | Unlimited |
|
||||||
|
| Site Certificate Monitoring | Limited to 1 | Unlimited |
|
||||||
|
| Automatic Deployment Plugins | Most plugins such as Alibaba Cloud CDN, Tencent Cloud, QiNiu CDN, Host Deployment, Baota, 1Panel | Synology |
|
||||||
|
| Notifications | Email, Custom Webhook | Email without configuration, WeChat Work, DingTalk, Lark, anpush, ServerChan, etc. |
|
||||||
|
|
||||||
|
************************
|
||||||
|
|
||||||
|
## 9. Contribute Code
|
||||||
|
|
||||||
|
1. For local development, please refer to the [Plugin Contribution Guide](https://certd.docmirror.cn/guide/development/).
|
||||||
|
2. As a contributor, you agree that your contributed code is subject to the following license:
|
||||||
|
1. The open-source license can be adjusted to be more or less restrictive.
|
||||||
|
2. It can be used for commercial purposes.
|
||||||
|
|
||||||
|
Thank you to the following contributors.
|
||||||
|
|
||||||
|
<a href="https://github.com/certd/certd/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=certd/certd" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
## 10. Open-Source License
|
||||||
|
* This project follows the GNU Affero General Public License (AGPL).
|
||||||
|
* Individuals and companies are allowed to use, copy, modify, and distribute this project freely for internal use. Any form of commercial use is prohibited without obtaining commercial authorization.
|
||||||
|
* Without commercial authorization, any modification of the logo, copyright information, and license-related code is prohibited.
|
||||||
|
* For commercial authorization, please contact the author.
|
||||||
|
|
||||||
|
## 11. My Other Projects (Please Star)
|
||||||
|
|
||||||
|
| Project Name | Stars | Project Description |
|
||||||
|
|----------------|---------------|--------------|
|
||||||
|
| [fast-crud](https://gitee.com/fast-crud/fast-crud/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/fast-crud/fast-crud?logo=github"/> | A fast CRUD development framework based on Vue3. |
|
||||||
|
| [dev-sidecar](https://github.com/docmirror/dev-sidecar/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/docmirror/dev-sidecar?logo=github"/> | A tool to access GitHub directly without a VPN, solving the problem of inaccessible GitHub. |
|
||||||
@@ -1 +1 @@
|
|||||||
23:51
|
10:51
|
||||||
|
|||||||
@@ -3,6 +3,152 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 某些插件找不到的bug ([4b3f4a8](https://github.com/certd/certd/commit/4b3f4a868a8b0800c5c59de9d0f47bddc079e7b3))
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复查看证书对话框翻译错误的bug ([8626b6d](https://github.com/certd/certd/commit/8626b6d9f235c511766f2ae98e0a37f6cebb621c))
|
||||||
|
* 修复translation后分组编辑打不开的bug ([46a1b74](https://github.com/certd/certd/commit/46a1b7479923d2feb2dece202a5932b99981b2cd))
|
||||||
|
* 执行windows nginx命令时,改为return code判断是否执行成功 ([b37cffd](https://github.com/certd/certd/commit/b37cffd704cd08b8bdd68a6e284706eabe59e78d))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化证书进度条颜色 ([2af91db](https://github.com/certd/certd/commit/2af91dbf2ae36a4ed17c6788bc2a2a79a3bb29f8))
|
||||||
|
* 站点证书即将过期通知标题颜色优化为红色 ([80c5331](https://github.com/certd/certd/commit/80c5331a5d4c320323d9b9b800e4ea3b72577b33))
|
||||||
|
* 支持部署到阿里云vod ([98da4e1](https://github.com/certd/certd/commit/98da4e1791ed8bb21daf2a9914fda875d14633c9))
|
||||||
|
* 支持部署证书到网宿CDN ([c3da026](https://github.com/certd/certd/commit/c3da026b33106f5195959825a68cadbe49efef00))
|
||||||
|
* 重置管理员密码同时可以清除管理员的2FA设置 ([1ece091](https://github.com/certd/certd/commit/1ece0915f172d5f8b8adb866434e7efcc5c8c46d))
|
||||||
|
* output-selector from参数支持更丰富的过滤规则 ([87853a2](https://github.com/certd/certd/commit/87853a201535f3bfe8505c40f8f5229d82ffcc73))
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复开放接口添加按钮文本显示问题 ([f93ba99](https://github.com/certd/certd/commit/f93ba9970c12680f38eba2a7abd4b72cf3f5b6a6))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化部署到腾讯TKE插件,支持Opaque类型选择,优化填写说明 ([1445325](https://github.com/certd/certd/commit/144532530a865b634e68539e4888e26f52f73492))
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复notification编辑按钮无法打开对话框的bug ([0cea26c](https://github.com/certd/certd/commit/0cea26c6287f52adf273b4a525c37bea8555c68c))
|
||||||
|
* 优化更新飞牛os证书有效期,修复某些情况下部署证书后飞牛无法访问https的bug ([610c919](https://github.com/certd/certd/commit/610c919c72037becc0ed326f5d5b18c963dfcb3a))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 证书检查支持自定义dns服务器 ([c53bb7c](https://github.com/certd/certd/commit/c53bb7cf677faa32729709ae0c10359db5194d7a))
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复通知和触发器无法编辑的bug ([a2e0951](https://github.com/certd/certd/commit/a2e09510426680eb425c0d7ad337f39d3f052054))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持部署到七牛云DCDN ([bde601b](https://github.com/certd/certd/commit/bde601bfffb4f7345d97e1e3b064520816d31555))
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 支持自定义证书生成插件 ([481cc02](https://github.com/certd/certd/commit/481cc029fafaf280aa844cd3ca30f4653ec35d55))
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* 支持模版创建流水线 ([2559f0e](https://github.com/certd/certd/commit/2559f0e822db095d1d26a7f1d517622dce22a5c2))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 阿里云waf cname站点选择支持翻页及域名查询 ([4cf9858](https://github.com/certd/certd/commit/4cf98584dacc5999752732f136246647a2f1f07d))
|
||||||
|
* 部署到ssh主机命令支持前置命令 ([991b741](https://github.com/certd/certd/commit/991b741cbe223b342f534157da63b71e81661f8e))
|
||||||
|
* 模版导入流水线 ([dcc8c56](https://github.com/certd/certd/commit/dcc8c569693432579709ce63656665a76bcf9a44))
|
||||||
|
* 添加用户资料编辑功能 ([7c0f43c](https://github.com/certd/certd/commit/7c0f43c8a3052f73afee3e93c9fcbc43c44ab690))
|
||||||
|
* 优化阿里云waf的日志信息 ([821c6d8](https://github.com/certd/certd/commit/821c6d807d4b3cc5092d09a6282b8cbafb9e7c9f))
|
||||||
|
* 优化中英文翻译与切换 ([acaa8b1](https://github.com/certd/certd/commit/acaa8b173183b4423584ee070e6e332e0ac0eb2d))
|
||||||
|
* 站点IP监控前先同步一下IP ([a080b60](https://github.com/certd/certd/commit/a080b606ab6e289d96b17ef7d2879b4603f889ba))
|
||||||
|
* 支持选择运行策略设置 ([60f055f](https://github.com/certd/certd/commit/60f055f293ce237c21cd9050333dad9609eceac1))
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 腾讯云授权支持设置是否国际站,部署到EO插件支持国际站 ([5cd3968](https://github.com/certd/certd/commit/5cd3968929acef333cf30d3b20cf21cea6c82c5f))
|
||||||
|
* 修复邮箱包含.号校验失败的bug ([65dcae7](https://github.com/certd/certd/commit/65dcae79f8faa7a6cb425e10a0fdb6758b0719f3))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 首次打开任务日志查看页面,自动滚动到底部 ([43fee42](https://github.com/certd/certd/commit/43fee42198e8697185b427b1fa3eb79409603393))
|
||||||
|
* 支持批量修改通知和定时 ([e11b3be](https://github.com/certd/certd/commit/e11b3becfd4abe6547e84d09adc38ebd6e1c4b87))
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持s3 access做测试 ([f00aeac](https://github.com/certd/certd/commit/f00aeacb8b5c81f0bafa4c1b76723dec2b6b7784))
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复消息内容存在()<>等括号情况下无法发送tg通知的bug ([c937583](https://github.com/certd/certd/commit/c937583a50d8513d76adead3648f83eee2fcc6f9))
|
||||||
|
* 修复重试次数设置无效的bug ([e2099ac](https://github.com/certd/certd/commit/e2099ac9ca344bc70bfa4219002e9138708973ae))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 授权列表类型颜色优化 ([1e86338](https://github.com/certd/certd/commit/1e863382d3d1a8cc95a1abf51e75bf6eaea3244f))
|
||||||
|
* 支持雨云dns解析 ([8354348](https://github.com/certd/certd/commit/83543487e7418683bd79cfe3b9e0d792bdb977f7))
|
||||||
|
* 支持雨云dns解析以及雨云证书更新 ([43c7a19](https://github.com/certd/certd/commit/43c7a1984926f5d4647760cc134bb0aede3a7b7a))
|
||||||
|
* github 版本检查支持执行脚本 ([bad3504](https://github.com/certd/certd/commit/bad3504d4a15e6989b967b66aa9da8c6981f25bf))
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复阿里云新加坡clb无法部署证书的bug ([c1fbc8c](https://github.com/certd/certd/commit/c1fbc8cd68ae020ef342e4e92f4d9b4869ca1ead))
|
||||||
|
* 修复阿里云新加坡clb无法部署证书的bug ([3e84e11](https://github.com/certd/certd/commit/3e84e116e863b54c6b4d7db160af372dacc5857f))
|
||||||
|
* 修复检查github release 插件无法保存最后版本的bug ([a92107c](https://github.com/certd/certd/commit/a92107cc47133883b099d5228b06373e84c8bb50))
|
||||||
|
* 修复站点监控定时器多次添加的bug ([9361679](https://github.com/certd/certd/commit/936167972fe83e519bc01a0dd961d9c0635d24ab))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 阿里云dns操作增加重试机制 ([424fd96](https://github.com/certd/certd/commit/424fd96615c05e949af8c837c261c1400bdffba2))
|
||||||
|
* 优化阿里云nlb支持部署扩展证书 ([9cbdfda](https://github.com/certd/certd/commit/9cbdfda829b231733d54c66c5024d46e6fc11af3))
|
||||||
|
* 子域名托管帮助链接优化为打开新窗口 ([7c0cdd1](https://github.com/certd/certd/commit/7c0cdd169e2f943e703e433677f2f437d4aa02ee))
|
||||||
|
* history增加触发类型显示 ([7f6070c](https://github.com/certd/certd/commit/7f6070c960ed7bf02add5ab36436de6573f2f1fa))
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 某些证书提供商的证书确实commonName导致无法转换证书的问题 ([ac87bc5](https://github.com/certd/certd/commit/ac87bc57e957ea4679707bfd38d6840e26319bed))
|
||||||
|
* 修复站点监控通知渠道设置无效的bug ([a00453c](https://github.com/certd/certd/commit/a00453c83a58114ce2873dd6e6aaf313f1ce0f87))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 修改 HTTPS 服务器监听地址 ([e1cf64a](https://github.com/certd/certd/commit/e1cf64ae16d4abfe4299ff16d5088c30cf3c6365))
|
||||||
|
* 优化流水线页面,增加下次执行时间、查看证书显示 ([c820315](https://github.com/certd/certd/commit/c8203154094fae3d17198747f49f5f41ddf29a4e))
|
||||||
|
* 站点证书监控支持定时设置,重试次数设置 ([d3c2f8e](https://github.com/certd/certd/commit/d3c2f8eb436e670772d14a54acd6b541c5aa3978))
|
||||||
|
* 证书申请支持letencrypt profile选项 ([2eb0e54](https://github.com/certd/certd/commit/2eb0e54909d8ad36708e07c12fd598998159bc43))
|
||||||
|
* aliyun alb支持部署扩展证书 ([2a19b61](https://github.com/certd/certd/commit/2a19b61b7a78620c06396c2cc37cc77d738b6d12))
|
||||||
|
|
||||||
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* 完善注释 ([6702ca1](https://github.com/certd/certd/commit/6702ca10a17f5d7dbff789b039f7269496f66b97))
|
||||||
|
* AWS 中国区 CloudFront 证书部署(IAM 证书) ([8a55bed](https://github.com/certd/certd/commit/8a55beda924b3be2a53b9ba80d9487cefa8bf887))
|
||||||
|
* **lego:** support for command options ([b84159f](https://github.com/certd/certd/commit/b84159f2f11531f058837c2e82d66499f3740f20))
|
||||||
|
|
||||||
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -10,15 +10,15 @@
|
|||||||
* 登录宝塔面板,在菜单栏中点击 Docker,首次进入会提示安装Docker服务,点击立即安装,按提示完成安装
|
* 登录宝塔面板,在菜单栏中点击 Docker,首次进入会提示安装Docker服务,点击立即安装,按提示完成安装
|
||||||
|
|
||||||
### 2、部署certd
|
### 2、部署certd
|
||||||
|
以下两种方式人选一种:
|
||||||
#### 2.1 应用商店一键部署【推荐】
|
#### 2.1 应用商店方式一键部署【推荐】
|
||||||
|
|
||||||
* 在宝塔Docker应用商店中找到`certd`(要先点右上角更新应用)
|
* 在宝塔Docker应用商店中找到`certd`(要先点右上角更新应用)
|
||||||
* 点击安装,配置域名等基本信息即可完成安装
|
* 点击安装,配置域名等基本信息即可完成安装
|
||||||
|
|
||||||
> 需要宝塔9.2.0及以上版本才支持
|
> 需要宝塔9.2.0及以上版本才支持
|
||||||
|
|
||||||
#### 2.2 容器编排部署
|
#### 2.2 容器编排方式部署
|
||||||
|
|
||||||
1. 打开`docker-compose.yaml`,整个内容复制下来
|
1. 打开`docker-compose.yaml`,整个内容复制下来
|
||||||
https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml
|
https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml
|
||||||
@@ -43,12 +43,15 @@ admin/123456
|
|||||||
## 三、如何升级
|
## 三、如何升级
|
||||||
宝塔升级certd非常简单
|
宝塔升级certd非常简单
|
||||||
|
|
||||||
`docker`->`容器编排`->`左侧选择Certd`->`更新镜像`
|
打开容器页面: `docker`->`容器编排`->`左侧选择Certd`->`更新镜像`
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## 四、数据备份
|
## 四、数据备份
|
||||||
|
|
||||||
|
部署方式不同,数据保存位置不同
|
||||||
|
|
||||||
### 4.1 应用商店部署方式
|
### 4.1 应用商店部署方式
|
||||||
点击进入安装路径,数据保存在`./data`目录下,可以手动备份
|
点击进入安装路径,数据保存在`./data`目录下,可以手动备份
|
||||||
|
|
||||||
@@ -62,7 +65,6 @@ admin/123456
|
|||||||
数据默认保存在`/data/certd`目录下,可以手动备份
|
数据默认保存在`/data/certd`目录下,可以手动备份
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 4.3 自动备份
|
### 4.3 自动备份
|
||||||
|
|
||||||
> 建议配置一条 [数据库备份流水线](../../use/backup/),自动备份
|
> 建议配置一条 [数据库备份流水线](../../use/backup/),自动备份
|
||||||
|
|||||||
BIN
docs/guide/install/images/github-release-2.png
Normal file
BIN
docs/guide/install/images/github-release-2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
BIN
docs/guide/install/images/github-release.png
Normal file
BIN
docs/guide/install/images/github-release.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
@@ -13,4 +13,54 @@
|
|||||||
:::
|
:::
|
||||||
|
|
||||||
## 升级日志
|
## 升级日志
|
||||||
|
可以查看最新版本号,以及所有版本的更新日志
|
||||||
[CHANGELOG](../changelogs/CHANGELOG.md)
|
[CHANGELOG](../changelogs/CHANGELOG.md)
|
||||||
|
|
||||||
|
|
||||||
|
## 自动升级配置
|
||||||
|
|
||||||
|
### 1. 方法一:使用watchtower监控
|
||||||
|
|
||||||
|
修改docker-compose.yaml文件增加如下配置, 使用watchtower监控自动升级
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
certd:
|
||||||
|
...
|
||||||
|
labels:
|
||||||
|
com.centurylinklabs.watchtower.enable: "true"
|
||||||
|
|
||||||
|
# ↓↓↓↓ --------------------------------------------------------- 自动升级,上面certd的版本号要保持为latest
|
||||||
|
certd-updater: # 添加 Watchtower 服务
|
||||||
|
image: containrrr/watchtower:latest
|
||||||
|
container_name: certd-updater
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
# 配置 自动更新
|
||||||
|
environment:
|
||||||
|
- WATCHTOWER_CLEANUP=true # 自动清理旧版本容器
|
||||||
|
- WATCHTOWER_INCLUDE_STOPPED=false # 不更新已停止的容器
|
||||||
|
- WATCHTOWER_LABEL_ENABLE=true # 根据容器标签进行更新
|
||||||
|
- WATCHTOWER_POLL_INTERVAL=600 # 每 10 分钟检查一次更新
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 2. 方法二:使用Certd版本监控功能
|
||||||
|
|
||||||
|
选择Github-检查Release版本插件
|
||||||
|

|
||||||
|
按如下图填写配置
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
检测到新版本后执行宿主机升级命令:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# 拉取最新镜像
|
||||||
|
docker pull registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
||||||
|
# 升级容器命令, 替换成你自己的certd更新命令
|
||||||
|
export RESTART_CERT='sleep 10; cd ~/deploy/certd/ ; docker compose down; docker compose up -d'
|
||||||
|
# 构造一个脚本10s后在后台执行,避免容器销毁时执行太快,导致流水线任务无法结束
|
||||||
|
nohup sh -c '$RESTART_CERT' >/dev/null 2>&1 & echo '10秒后重启' && exit
|
||||||
|
```
|
||||||
@@ -18,4 +18,13 @@ header中传入x-certd-token即可调用开放接口
|
|||||||
4、然后将content和sign分别base64后用.号连接: x-certd-token = base64(content) +"."+base64(sign)
|
4、然后将content和sign分别base64后用.号连接: x-certd-token = base64(content) +"."+base64(sign)
|
||||||
|
|
||||||
## SDK
|
## SDK
|
||||||
待开发
|
待开发
|
||||||
|
|
||||||
|
## 客户端工具
|
||||||
|
|
||||||
|
### SSL-Assistant
|
||||||
|
`SSL Assistant` 是一个基于 Go 语言开发的跨平台证书部署管理助手。
|
||||||
|
支持自动扫描主机`Nginx`配置,然后从Certd拉取证书并部署。
|
||||||
|
在不想暴露ssh主机密码情况下,该工具非常好用。
|
||||||
|
|
||||||
|
开源地址: https://github.com/Youngxj/SSL-Assistant
|
||||||
@@ -9,5 +9,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npmClient": "pnpm",
|
"npmClient": "pnpm",
|
||||||
"version": "1.35.0"
|
"version": "1.36.5"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
"afterpublishOnly": "npm run copylogs && time /t >build.trigger && git add ./build.trigger && git commit -m \"build: trigger build image\" && TIMEOUT /T 10 && git push",
|
"afterpublishOnly": "npm run copylogs && time /t >build.trigger && git add ./build.trigger && git commit -m \"build: trigger build image\" && TIMEOUT /T 10 && git push",
|
||||||
"transform-sql": "cd ./packages/ui/certd-server/db/ && node --experimental-json-modules transform.js",
|
"transform-sql": "cd ./packages/ui/certd-server/db/ && node --experimental-json-modules transform.js",
|
||||||
"commitAll": "git add . && git commit -m \"build: publish\" && git push && npm run commitPro",
|
"commitAll": "git add . && git commit -m \"build: publish\" && git push && npm run commitPro",
|
||||||
"commitPro": "cd ./packages/core/ && git add . && git commit -m \"build: publish\" && git push",
|
"commitPro": "cd ./packages/pro/ && git add . && git commit -m \"build: publish\" && git push",
|
||||||
"copylogs": "copyfiles \"CHANGELOG.md\" ./docs/guide/changelogs/",
|
"copylogs": "copyfiles \"CHANGELOG.md\" ./docs/guide/changelogs/",
|
||||||
"prepublishOnly1": "npm run check && lerna run build ",
|
"prepublishOnly1": "npm run check && lerna run build ",
|
||||||
"prepublishOnly2": "npm run check && npm run before-build && lerna run build ",
|
"prepublishOnly2": "npm run check && npm run before-build && lerna run build ",
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
"deploy1": "node --experimental-json-modules deploy.js ",
|
"deploy1": "node --experimental-json-modules deploy.js ",
|
||||||
"check": "node --experimental-json-modules publish-check.js",
|
"check": "node --experimental-json-modules publish-check.js",
|
||||||
"init": "lerna run build",
|
"init": "lerna run build",
|
||||||
|
"init:dev": "lerna run build",
|
||||||
"docs:dev": "vitepress dev docs",
|
"docs:dev": "vitepress dev docs",
|
||||||
"docs:build": "vitepress build docs",
|
"docs:build": "vitepress build docs",
|
||||||
"docs:preview": "vitepress preview docs",
|
"docs:preview": "vitepress preview docs",
|
||||||
|
|||||||
@@ -3,6 +3,52 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/publishlab/node-acme-client/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/publishlab/node-acme-client/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/publishlab/node-acme-client/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/publishlab/node-acme-client/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/publishlab/node-acme-client/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/publishlab/node-acme-client/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/publishlab/node-acme-client/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/publishlab/node-acme-client/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/publishlab/node-acme-client/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/publishlab/node-acme-client/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/publishlab/node-acme-client/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 证书申请支持letencrypt profile选项 ([2eb0e54](https://github.com/publishlab/node-acme-client/commit/2eb0e54909d8ad36708e07c12fd598998159bc43))
|
||||||
|
|
||||||
# [1.35.0](https://github.com/publishlab/node-acme-client/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/publishlab/node-acme-client/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/acme-client
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "Simple and unopinionated ACME client",
|
"description": "Simple and unopinionated ACME client",
|
||||||
"private": false,
|
"private": false,
|
||||||
"author": "nmorsman",
|
"author": "nmorsman",
|
||||||
"version": "1.35.0",
|
"version": "1.36.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"module": "scr/index.js",
|
"module": "scr/index.js",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
"types"
|
"types"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.35.0",
|
"@certd/basic": "^1.36.5",
|
||||||
"@peculiar/x509": "^1.11.0",
|
"@peculiar/x509": "^1.11.0",
|
||||||
"asn1js": "^3.0.5",
|
"asn1js": "^3.0.5",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
@@ -69,5 +69,5 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||||
},
|
},
|
||||||
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ export default async (client, userOpts) => {
|
|||||||
|
|
||||||
log("[auto] Placing new certificate order with ACME provider");
|
log("[auto] Placing new certificate order with ACME provider");
|
||||||
const orderPayload = { identifiers: uniqueDomains.map((d) => ({ type: "dns", value: d })) };
|
const orderPayload = { identifiers: uniqueDomains.map((d) => ({ type: "dns", value: d })) };
|
||||||
|
if (opts.profile && client.sslProvider === 'letsencrypt' ){
|
||||||
|
orderPayload.profile = opts.profile;
|
||||||
|
}
|
||||||
const order = await client.createOrder(orderPayload);
|
const order = await client.createOrder(orderPayload);
|
||||||
const authorizations = await client.getAuthorizations(order);
|
const authorizations = await client.getAuthorizations(order);
|
||||||
|
|
||||||
@@ -213,12 +216,16 @@ export default async (client, userOpts) => {
|
|||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runPromisePa(tasks, waitTime = 5000) {
|
async function runPromisePa(tasks, waitTime = 8000) {
|
||||||
const results = [];
|
const results = [];
|
||||||
|
let j = 0
|
||||||
// eslint-disable-next-line no-await-in-loop,no-restricted-syntax
|
// eslint-disable-next-line no-await-in-loop,no-restricted-syntax
|
||||||
for (const task of tasks) {
|
for (const task of tasks) {
|
||||||
|
j++
|
||||||
|
log(`开始第${j}个任务`);
|
||||||
results.push(task());
|
results.push(task());
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
log(`wait ${Math.floor(waitTime/1000)}s`)
|
||||||
await wait(waitTime);
|
await wait(waitTime);
|
||||||
}
|
}
|
||||||
return Promise.all(results);
|
return Promise.all(results);
|
||||||
@@ -242,6 +249,7 @@ export default async (client, userOpts) => {
|
|||||||
log(`跳过本地验证(skipChallengeVerification=true),等待 60s`);
|
log(`跳过本地验证(skipChallengeVerification=true),等待 60s`);
|
||||||
await wait(60 * 1000);
|
await wait(60 * 1000);
|
||||||
} else {
|
} else {
|
||||||
|
log("开始本地校验")
|
||||||
await runPromisePa(localVerifyTasks, 1000);
|
await runPromisePa(localVerifyTasks, 1000);
|
||||||
log(`本地校验完成,等待${waitDnsDiffuseTime}s`)
|
log(`本地校验完成,等待${waitDnsDiffuseTime}s`)
|
||||||
await wait(waitDnsDiffuseTime * 1000)
|
await wait(waitDnsDiffuseTime * 1000)
|
||||||
|
|||||||
@@ -90,10 +90,12 @@ const defaultOpts = {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class AcmeClient {
|
class AcmeClient {
|
||||||
|
sslProvider
|
||||||
constructor(opts) {
|
constructor(opts) {
|
||||||
if (!Buffer.isBuffer(opts.accountKey)) {
|
if (!Buffer.isBuffer(opts.accountKey)) {
|
||||||
opts.accountKey = Buffer.from(opts.accountKey);
|
opts.accountKey = Buffer.from(opts.accountKey);
|
||||||
}
|
}
|
||||||
|
this.sslProvider = opts.sslProvider;
|
||||||
|
|
||||||
this.opts = { ...defaultOpts, ...opts };
|
this.opts = { ...defaultOpts, ...opts };
|
||||||
this.backoffOpts = {
|
this.backoffOpts = {
|
||||||
|
|||||||
1
packages/core/acme-client/types/index.d.ts
vendored
1
packages/core/acme-client/types/index.d.ts
vendored
@@ -66,6 +66,7 @@ export interface ClientAutoOptions {
|
|||||||
challengePriority?: string[];
|
challengePriority?: string[];
|
||||||
preferredChain?: string;
|
preferredChain?: string;
|
||||||
signal?: AbortSignal;
|
signal?: AbortSignal;
|
||||||
|
profile?:string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Client {
|
export class Client {
|
||||||
|
|||||||
@@ -3,6 +3,52 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 证书检查支持自定义dns服务器 ([c53bb7c](https://github.com/certd/certd/commit/c53bb7cf677faa32729709ae0c10359db5194d7a))
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/basic
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
00:09
|
10:46
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/basic",
|
"name": "@certd/basic",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.35.0",
|
"version": "1.36.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -45,5 +45,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import { locker } from "./util.lock.js";
|
|||||||
import { mitter } from "./util.mitter.js";
|
import { mitter } from "./util.mitter.js";
|
||||||
|
|
||||||
import * as request from "./util.request.js";
|
import * as request from "./util.request.js";
|
||||||
|
export * from "./util.cache.js";
|
||||||
export const utils = {
|
export const utils = {
|
||||||
sleep,
|
sleep,
|
||||||
http,
|
http,
|
||||||
|
|||||||
@@ -1,8 +1,53 @@
|
|||||||
// LRUCache
|
// LRUCache
|
||||||
|
|
||||||
import { LRUCache } from 'lru-cache';
|
import { LRUCache } from "lru-cache";
|
||||||
|
|
||||||
export const cache = new LRUCache<string, any>({
|
export const cache = new LRUCache<string, any>({
|
||||||
max: 1000,
|
max: 1000,
|
||||||
ttl: 1000 * 60 * 10,
|
ttl: 1000 * 60 * 10,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export class LocalCache<V = any> {
|
||||||
|
cache: Map<string, { value: V; expiresAt: number }>;
|
||||||
|
constructor(opts: { clearInterval?: number } = {}) {
|
||||||
|
this.cache = new Map();
|
||||||
|
setInterval(() => {
|
||||||
|
this.clearExpires();
|
||||||
|
}, opts.clearInterval ?? 5 * 60 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
get(key: string): V | undefined {
|
||||||
|
const entry = this.cache.get(key);
|
||||||
|
if (!entry) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否过期
|
||||||
|
if (Date.now() > entry.expiresAt) {
|
||||||
|
this.cache.delete(key);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set(key: string, value: V, ttl = 300000) {
|
||||||
|
// 默认5分钟 (300000毫秒)
|
||||||
|
this.cache.set(key, {
|
||||||
|
value,
|
||||||
|
expiresAt: Date.now() + ttl,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
clearExpires() {
|
||||||
|
for (const [key, entry] of this.cache) {
|
||||||
|
if (entry.expiresAt < Date.now()) {
|
||||||
|
this.cache.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default function (timeout: number) {
|
export default function (timeout: number) {
|
||||||
return new Promise((resolve) => {
|
return new Promise(resolve => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
resolve({});
|
resolve({});
|
||||||
}, timeout);
|
}, timeout);
|
||||||
|
|||||||
@@ -3,6 +3,59 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 阿里云waf cname站点选择支持翻页及域名查询 ([4cf9858](https://github.com/certd/certd/commit/4cf98584dacc5999752732f136246647a2f1f07d))
|
||||||
|
* 支持选择运行策略设置 ([60f055f](https://github.com/certd/certd/commit/60f055f293ce237c21cd9050333dad9609eceac1))
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持批量修改通知和定时 ([e11b3be](https://github.com/certd/certd/commit/e11b3becfd4abe6547e84d09adc38ebd6e1c4b87))
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持s3 access做测试 ([f00aeac](https://github.com/certd/certd/commit/f00aeacb8b5c81f0bafa4c1b76723dec2b6b7784))
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复消息内容存在()<>等括号情况下无法发送tg通知的bug ([c937583](https://github.com/certd/certd/commit/c937583a50d8513d76adead3648f83eee2fcc6f9))
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/pipeline
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/pipeline",
|
"name": "@certd/pipeline",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.35.0",
|
"version": "1.36.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
"pub": "npm publish"
|
"pub": "npm publish"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.35.0",
|
"@certd/basic": "^1.36.5",
|
||||||
"@certd/plus-core": "^1.35.0",
|
"@certd/plus-core": "^1.36.5",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"reflect-metadata": "^0.1.13"
|
"reflect-metadata": "^0.1.13"
|
||||||
@@ -44,5 +44,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export type AccessContext = {
|
|||||||
http: HttpClient;
|
http: HttpClient;
|
||||||
logger: ILogger;
|
logger: ILogger;
|
||||||
utils: typeof utils;
|
utils: typeof utils;
|
||||||
|
accessService: IAccessService;
|
||||||
};
|
};
|
||||||
|
|
||||||
export abstract class BaseAccess implements IAccess {
|
export abstract class BaseAccess implements IAccess {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// src/decorator/memoryCache.decorator.ts
|
// src/decorator/memoryCache.decorator.ts
|
||||||
import { AccessContext, AccessDefine, AccessInputDefine } from "./api.js";
|
import { AccessContext, AccessDefine, AccessInputDefine, IAccessService } from "./api.js";
|
||||||
import { Decorator } from "../decorator/index.js";
|
import { Decorator } from "../decorator/index.js";
|
||||||
import * as _ from "lodash-es";
|
import * as _ from "lodash-es";
|
||||||
import { accessRegistry } from "./registry.js";
|
import { accessRegistry } from "./registry.js";
|
||||||
@@ -41,7 +41,7 @@ export function AccessInput(input?: AccessInputDefine): PropertyDecorator {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function newAccess(type: string, input: any, ctx?: AccessContext) {
|
export async function newAccess(type: string, input: any, accessService: IAccessService, ctx?: AccessContext) {
|
||||||
const register = accessRegistry.get(type);
|
const register = accessRegistry.get(type);
|
||||||
if (register == null) {
|
if (register == null) {
|
||||||
throw new Error(`access ${type} not found`);
|
throw new Error(`access ${type} not found`);
|
||||||
@@ -58,6 +58,7 @@ export async function newAccess(type: string, input: any, ctx?: AccessContext) {
|
|||||||
http,
|
http,
|
||||||
logger,
|
logger,
|
||||||
utils,
|
utils,
|
||||||
|
accessService,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
access.setCtx(ctx);
|
access.setCtx(ctx);
|
||||||
|
|||||||
@@ -3,17 +3,35 @@ import { IContext } from "../core/index.js";
|
|||||||
export type UserContext = IContext;
|
export type UserContext = IContext;
|
||||||
export type PipelineContext = IContext;
|
export type PipelineContext = IContext;
|
||||||
|
|
||||||
export type PageReq = {
|
export type PageSearch = {
|
||||||
offset?: number;
|
pageNo?: number;
|
||||||
limit?: number;
|
pageSize?: number;
|
||||||
searchKey?: string;
|
searchKey?: string;
|
||||||
// sortBy?: string;
|
// sortBy?: string;
|
||||||
// sortOrder?: "asc" | "desc";
|
// sortOrder?: "asc" | "desc";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export type PageRes = {
|
export type PageRes = {
|
||||||
offset?: number;
|
pageNo?: number;
|
||||||
limit?: number;
|
pageSize?: number;
|
||||||
total?: string;
|
total?: string;
|
||||||
list: any[];
|
list: any[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export class Pager {
|
||||||
|
pageNo: number;
|
||||||
|
pageSize: number;
|
||||||
|
constructor(req: PageSearch) {
|
||||||
|
this.pageNo = req.pageNo ?? 1;
|
||||||
|
this.pageSize = req.pageSize || 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
getOffset() {
|
||||||
|
return (this.pageNo - 1) * (this.pageSize ?? 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
setOffset(offset: number) {
|
||||||
|
this.pageNo = Math.ceil(offset / (this.pageSize ?? 50)) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -452,12 +452,12 @@ export class Executor {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notification.type === "email") {
|
if (notification.type === "email" && notification.options?.receivers) {
|
||||||
try {
|
try {
|
||||||
await this.options.emailService?.send({
|
await this.options.emailService?.send({
|
||||||
subject,
|
subject,
|
||||||
content,
|
content,
|
||||||
receivers: notification.options.receivers,
|
receivers: notification.options?.receivers,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error("send email error", e);
|
logger.error("send email error", e);
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ export type Stage = Runnable & {
|
|||||||
export type Trigger = {
|
export type Trigger = {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
cron: string;
|
props: {
|
||||||
|
cron: string;
|
||||||
|
};
|
||||||
type: string;
|
type: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -78,14 +80,13 @@ export type EmailOptions = {
|
|||||||
receivers: string[];
|
receivers: string[];
|
||||||
};
|
};
|
||||||
export type NotificationWhen = "error" | "success" | "turnToSuccess" | "start";
|
export type NotificationWhen = "error" | "success" | "turnToSuccess" | "start";
|
||||||
export type NotificationType = "email" | "url";
|
export type NotificationType = "email" | "other";
|
||||||
export type Notification = {
|
export type Notification = {
|
||||||
type: NotificationType;
|
type: NotificationType;
|
||||||
when: NotificationWhen[];
|
when: NotificationWhen[];
|
||||||
options: EmailOptions;
|
options?: EmailOptions;
|
||||||
notificationId: number;
|
notificationId: number;
|
||||||
title: string;
|
title: string;
|
||||||
subType: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Pipeline = Runnable & {
|
export type Pipeline = Runnable & {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { FormItemProps, HistoryResult, Pipeline } from "../dt/index.js";
|
|||||||
import { HttpClient, ILogger, utils } from "@certd/basic";
|
import { HttpClient, ILogger, utils } from "@certd/basic";
|
||||||
import * as _ from "lodash-es";
|
import * as _ from "lodash-es";
|
||||||
import { IEmailService } from "../service/index.js";
|
import { IEmailService } from "../service/index.js";
|
||||||
import { isPlus } from "@certd/plus-core";
|
|
||||||
|
|
||||||
export type NotificationBody = {
|
export type NotificationBody = {
|
||||||
userId?: number;
|
userId?: number;
|
||||||
@@ -81,9 +80,6 @@ export abstract class BaseNotification implements INotification {
|
|||||||
logger!: ILogger;
|
logger!: ILogger;
|
||||||
|
|
||||||
async doSend(body: NotificationBody) {
|
async doSend(body: NotificationBody) {
|
||||||
if (this.define.needPlus && !isPlus()) {
|
|
||||||
body.content = `${body.content}\n\n注意:此通知渠道已调整为专业版功能,后续版本将不再支持发送,请尽快修改或升级为专业版`;
|
|
||||||
}
|
|
||||||
return await this.send(body);
|
return await this.send(body);
|
||||||
}
|
}
|
||||||
abstract send(body: NotificationBody): Promise<void>;
|
abstract send(body: NotificationBody): Promise<void>;
|
||||||
@@ -121,9 +117,13 @@ export abstract class BaseNotification implements INotification {
|
|||||||
async onTestRequest() {
|
async onTestRequest() {
|
||||||
return await this.doSend({
|
return await this.doSend({
|
||||||
userId: 0,
|
userId: 0,
|
||||||
title: "【Certd】测试通知【*.foo.com】,标题长度测试、测试、测试",
|
title: "【标题】测试通知【*.foo.com】,标题长度测试、测试、测试",
|
||||||
content: `测试通知,*.foo.com
|
content: `测试通知
|
||||||
|
域名测试: *.foo.com
|
||||||
换行测试
|
换行测试
|
||||||
|
(括号测试)
|
||||||
|
<尖括号测试>
|
||||||
|
[中括号测试]
|
||||||
`,
|
`,
|
||||||
pipeline: {
|
pipeline: {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|||||||
@@ -3,6 +3,50 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-huawei
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-huawei",
|
"name": "@certd/lib-huawei",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.35.0",
|
"version": "1.36.5",
|
||||||
"main": "./dist/bundle.js",
|
"main": "./dist/bundle.js",
|
||||||
"module": "./dist/bundle.js",
|
"module": "./dist/bundle.js",
|
||||||
"types": "./dist/d/index.d.ts",
|
"types": "./dist/d/index.d.ts",
|
||||||
@@ -24,5 +24,5 @@
|
|||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"tslib": "^2.8.1"
|
"tslib": "^2.8.1"
|
||||||
},
|
},
|
||||||
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,50 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-iframe
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-iframe",
|
"name": "@certd/lib-iframe",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.35.0",
|
"version": "1.36.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -31,5 +31,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,50 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/jdcloud
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/jdcloud",
|
"name": "@certd/jdcloud",
|
||||||
"version": "1.35.0",
|
"version": "1.36.5",
|
||||||
"description": "jdcloud openApi sdk",
|
"description": "jdcloud openApi sdk",
|
||||||
"main": "./dist/bundle.js",
|
"main": "./dist/bundle.js",
|
||||||
"module": "./dist/bundle.js",
|
"module": "./dist/bundle.js",
|
||||||
@@ -61,5 +61,5 @@
|
|||||||
"fetch"
|
"fetch"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,50 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-k8s
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-k8s",
|
"name": "@certd/lib-k8s",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.35.0",
|
"version": "1.36.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
"pub": "npm publish"
|
"pub": "npm publish"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.35.0",
|
"@certd/basic": "^1.36.5",
|
||||||
"@kubernetes/client-node": "0.21.0"
|
"@kubernetes/client-node": "0.21.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -32,5 +32,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,52 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持s3 access做测试 ([f00aeac](https://github.com/certd/certd/commit/f00aeacb8b5c81f0bafa4c1b76723dec2b6b7784))
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-server
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-server",
|
"name": "@certd/lib-server",
|
||||||
"version": "1.35.0",
|
"version": "1.36.5",
|
||||||
"description": "midway with flyway, sql upgrade way ",
|
"description": "midway with flyway, sql upgrade way ",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -27,10 +27,10 @@
|
|||||||
],
|
],
|
||||||
"license": "AGPL",
|
"license": "AGPL",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/acme-client": "^1.35.0",
|
"@certd/acme-client": "^1.36.5",
|
||||||
"@certd/basic": "^1.35.0",
|
"@certd/basic": "^1.36.5",
|
||||||
"@certd/pipeline": "^1.35.0",
|
"@certd/pipeline": "^1.36.5",
|
||||||
"@certd/plus-core": "^1.35.0",
|
"@certd/plus-core": "^1.36.5",
|
||||||
"@midwayjs/cache": "~3.14.0",
|
"@midwayjs/cache": "~3.14.0",
|
||||||
"@midwayjs/core": "~3.20.3",
|
"@midwayjs/core": "~3.20.3",
|
||||||
"@midwayjs/i18n": "~3.20.3",
|
"@midwayjs/i18n": "~3.20.3",
|
||||||
@@ -61,5 +61,5 @@
|
|||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ export abstract class BaseService<T> {
|
|||||||
...where,
|
...where,
|
||||||
});
|
});
|
||||||
await this.modifyAfter(idArr);
|
await this.modifyAfter(idArr);
|
||||||
|
return ids
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveIdArr(ids: string | any[]) {
|
resolveIdArr(ids: string | any[]) {
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core';
|
||||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
import {InjectEntityModel} from '@midwayjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { In, Repository } from "typeorm";
|
||||||
import { BaseService, PageReq, PermissionException, ValidateException } from '../../../index.js';
|
import {AccessGetter, BaseService, PageReq, PermissionException, ValidateException} from '../../../index.js';
|
||||||
import { AccessEntity } from '../entity/access.js';
|
import {AccessEntity} from '../entity/access.js';
|
||||||
import { AccessDefine, accessRegistry, newAccess } from '@certd/pipeline';
|
import {AccessDefine, accessRegistry, newAccess} from '@certd/pipeline';
|
||||||
import { EncryptService } from './encrypt-service.js';
|
import {EncryptService} from './encrypt-service.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 授权
|
* 授权
|
||||||
*/
|
*/
|
||||||
@Provide()
|
@Provide()
|
||||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
@Scope(ScopeEnum.Request, {allowDowngrade: true})
|
||||||
export class AccessService extends BaseService<AccessEntity> {
|
export class AccessService extends BaseService<AccessEntity> {
|
||||||
@InjectEntityModel(AccessEntity)
|
@InjectEntityModel(AccessEntity)
|
||||||
repository: Repository<AccessEntity>;
|
repository: Repository<AccessEntity>;
|
||||||
@@ -95,6 +95,7 @@ export class AccessService extends BaseService<AccessEntity> {
|
|||||||
param.encryptSetting = JSON.stringify(encryptSetting);
|
param.encryptSetting = JSON.stringify(encryptSetting);
|
||||||
param.setting = JSON.stringify(json);
|
param.setting = JSON.stringify(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改
|
* 修改
|
||||||
* @param param 数据
|
* @param param 数据
|
||||||
@@ -140,7 +141,8 @@ export class AccessService extends BaseService<AccessEntity> {
|
|||||||
id: entity.id,
|
id: entity.id,
|
||||||
...setting,
|
...setting,
|
||||||
};
|
};
|
||||||
return await newAccess(entity.type, input);
|
const accessGetter = new AccessGetter(userId, this.getById.bind(this));
|
||||||
|
return await newAccess(entity.type, input,accessGetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getById(id: any, userId: number): Promise<any> {
|
async getById(id: any, userId: number): Promise<any> {
|
||||||
@@ -173,4 +175,27 @@ export class AccessService extends BaseService<AccessEntity> {
|
|||||||
getDefineByType(type: string) {
|
getDefineByType(type: string) {
|
||||||
return accessRegistry.getDefine(type);
|
return accessRegistry.getDefine(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async getSimpleByIds(ids: number[], userId: any) {
|
||||||
|
if (ids.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (!userId) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return await this.repository.find({
|
||||||
|
where: {
|
||||||
|
id: In(ids),
|
||||||
|
userId,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
type: true,
|
||||||
|
userId:true
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,50 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/midway-flyway-js",
|
"name": "@certd/midway-flyway-js",
|
||||||
"version": "1.35.0",
|
"version": "1.36.5",
|
||||||
"description": "midway with flyway, sql upgrade way ",
|
"description": "midway with flyway, sql upgrade way ",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -46,5 +46,5 @@
|
|||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,62 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化证书进度条颜色 ([2af91db](https://github.com/certd/certd/commit/2af91dbf2ae36a4ed17c6788bc2a2a79a3bb29f8))
|
||||||
|
* 支持部署到阿里云vod ([98da4e1](https://github.com/certd/certd/commit/98da4e1791ed8bb21daf2a9914fda875d14633c9))
|
||||||
|
* output-selector from参数支持更丰富的过滤规则 ([87853a2](https://github.com/certd/certd/commit/87853a201535f3bfe8505c40f8f5229d82ffcc73))
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 模版导入流水线 ([dcc8c56](https://github.com/certd/certd/commit/dcc8c569693432579709ce63656665a76bcf9a44))
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 某些证书提供商的证书确实commonName导致无法转换证书的问题 ([ac87bc5](https://github.com/certd/certd/commit/ac87bc57e957ea4679707bfd38d6840e26319bed))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 证书申请支持letencrypt profile选项 ([2eb0e54](https://github.com/certd/certd/commit/2eb0e54909d8ad36708e07c12fd598998159bc43))
|
||||||
|
|
||||||
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/plugin-cert",
|
"name": "@certd/plugin-cert",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.35.0",
|
"version": "1.36.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -16,10 +16,10 @@
|
|||||||
"pub": "npm publish"
|
"pub": "npm publish"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/acme-client": "^1.35.0",
|
"@certd/acme-client": "^1.36.5",
|
||||||
"@certd/basic": "^1.35.0",
|
"@certd/basic": "^1.36.5",
|
||||||
"@certd/pipeline": "^1.35.0",
|
"@certd/pipeline": "^1.36.5",
|
||||||
"@certd/plugin-lib": "^1.35.0",
|
"@certd/plugin-lib": "^1.36.5",
|
||||||
"@google-cloud/publicca": "^1.3.0",
|
"@google-cloud/publicca": "^1.3.0",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
@@ -43,5 +43,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,3 +59,38 @@ export interface ISubDomainsGetter {
|
|||||||
export interface IDomainParser {
|
export interface IDomainParser {
|
||||||
parse(fullDomain: string): Promise<string>;
|
parse(fullDomain: string): Promise<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type DnsVerifier = {
|
||||||
|
// dns直接校验
|
||||||
|
dnsProviderType?: string;
|
||||||
|
dnsProviderAccessId?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CnameVerifier = {
|
||||||
|
hostRecord: string;
|
||||||
|
domain: string;
|
||||||
|
recordValue: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type HttpVerifier = {
|
||||||
|
// http校验
|
||||||
|
httpUploaderType: string;
|
||||||
|
httpUploaderAccess: number;
|
||||||
|
httpUploadRootDir: string;
|
||||||
|
};
|
||||||
|
export type DomainVerifier = {
|
||||||
|
domain: string;
|
||||||
|
mainDomain: string;
|
||||||
|
type: string;
|
||||||
|
dns?: DnsVerifier;
|
||||||
|
cname?: CnameVerifier;
|
||||||
|
http?: HttpVerifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DomainVerifiers = {
|
||||||
|
[key: string]: DomainVerifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface IDomainVerifierGetter {
|
||||||
|
getVerifiers(domains: string[]): Promise<DomainVerifiers>;
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,10 +23,11 @@ export type HttpVerifyPlan = {
|
|||||||
|
|
||||||
export type DomainVerifyPlan = {
|
export type DomainVerifyPlan = {
|
||||||
domain: string;
|
domain: string;
|
||||||
|
mainDomain: string;
|
||||||
type: "cname" | "dns" | "http";
|
type: "cname" | "dns" | "http";
|
||||||
dnsProvider?: IDnsProvider;
|
dnsProvider?: IDnsProvider;
|
||||||
cnameVerifyPlan?: Record<string, CnameVerifyPlan>;
|
cnameVerifyPlan?: CnameVerifyPlan;
|
||||||
httpVerifyPlan?: Record<string, HttpVerifyPlan>;
|
httpVerifyPlan?: HttpVerifyPlan;
|
||||||
};
|
};
|
||||||
export type DomainsVerifyPlan = {
|
export type DomainsVerifyPlan = {
|
||||||
[key: string]: DomainVerifyPlan;
|
[key: string]: DomainVerifyPlan;
|
||||||
@@ -233,23 +234,20 @@ export class AcmeService {
|
|||||||
let dnsProvider = providers.dnsProvider;
|
let dnsProvider = providers.dnsProvider;
|
||||||
let fullRecord = `_acme-challenge.${fullDomain}`;
|
let fullRecord = `_acme-challenge.${fullDomain}`;
|
||||||
|
|
||||||
const origDomain = punycode.toUnicode(domain);
|
// const origDomain = punycode.toUnicode(domain);
|
||||||
const origFullDomain = punycode.toUnicode(fullDomain);
|
const origFullDomain = punycode.toUnicode(fullDomain);
|
||||||
if (providers.domainsVerifyPlan) {
|
if (providers.domainsVerifyPlan) {
|
||||||
//按照计划执行
|
//按照计划执行
|
||||||
const domainVerifyPlan = providers.domainsVerifyPlan[origDomain];
|
const domainVerifyPlan = providers.domainsVerifyPlan[origFullDomain];
|
||||||
if (domainVerifyPlan) {
|
if (domainVerifyPlan) {
|
||||||
if (domainVerifyPlan.type === "dns") {
|
if (domainVerifyPlan.type === "dns") {
|
||||||
dnsProvider = domainVerifyPlan.dnsProvider;
|
dnsProvider = domainVerifyPlan.dnsProvider;
|
||||||
} else if (domainVerifyPlan.type === "cname") {
|
} else if (domainVerifyPlan.type === "cname") {
|
||||||
const cnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan;
|
const cname: CnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan;
|
||||||
if (cnameVerifyPlan) {
|
if (cname) {
|
||||||
const cname = cnameVerifyPlan[origFullDomain];
|
dnsProvider = cname.dnsProvider;
|
||||||
if (cname) {
|
domain = await this.options.domainParser.parse(cname.domain);
|
||||||
dnsProvider = cname.dnsProvider;
|
fullRecord = cname.fullRecord;
|
||||||
domain = await this.options.domainParser.parse(cname.domain);
|
|
||||||
fullRecord = cname.fullRecord;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.logger.error(`未找到域名${fullDomain}的CNAME校验计划,请修改证书申请配置`);
|
this.logger.error(`未找到域名${fullDomain}的CNAME校验计划,请修改证书申请配置`);
|
||||||
}
|
}
|
||||||
@@ -257,13 +255,12 @@ export class AcmeService {
|
|||||||
throw new Error(`未找到域名${fullDomain}CNAME校验计划的DnsProvider,请修改证书申请配置`);
|
throw new Error(`未找到域名${fullDomain}CNAME校验计划的DnsProvider,请修改证书申请配置`);
|
||||||
}
|
}
|
||||||
} else if (domainVerifyPlan.type === "http") {
|
} else if (domainVerifyPlan.type === "http") {
|
||||||
const httpVerifyPlan = domainVerifyPlan.httpVerifyPlan;
|
const plan: HttpVerifyPlan = domainVerifyPlan.httpVerifyPlan;
|
||||||
if (httpVerifyPlan) {
|
if (plan) {
|
||||||
const httpChallenge = getChallenge("http-01");
|
const httpChallenge = getChallenge("http-01");
|
||||||
if (httpChallenge == null) {
|
if (httpChallenge == null) {
|
||||||
throw new Error("该域名不支持http-01方式校验");
|
throw new Error("该域名不支持http-01方式校验");
|
||||||
}
|
}
|
||||||
const plan = httpVerifyPlan[fullDomain];
|
|
||||||
return await doHttpVerify(httpChallenge, plan.httpUploader);
|
return await doHttpVerify(httpChallenge, plan.httpUploader);
|
||||||
} else {
|
} else {
|
||||||
throw new Error("未找到域名【" + fullDomain + "】的http校验配置");
|
throw new Error("未找到域名【" + fullDomain + "】的http校验配置");
|
||||||
@@ -272,9 +269,12 @@ export class AcmeService {
|
|||||||
throw new Error("不支持的校验类型", domainVerifyPlan.type);
|
throw new Error("不支持的校验类型", domainVerifyPlan.type);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.logger.info("未找到域名校验计划,使用默认的dnsProvider");
|
this.logger.warn(`未找到域名${fullDomain}的校验计划,使用默认的dnsProvider`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!dnsProvider) {
|
||||||
|
throw new Error(`域名${fullDomain}没有匹配到任何校验方式,证书申请失败`);
|
||||||
|
}
|
||||||
|
|
||||||
const dnsChallenge = getChallenge("dns-01");
|
const dnsChallenge = getChallenge("dns-01");
|
||||||
return await doDnsVerify(dnsChallenge, fullRecord, dnsProvider);
|
return await doDnsVerify(dnsChallenge, fullRecord, dnsProvider);
|
||||||
@@ -327,8 +327,9 @@ export class AcmeService {
|
|||||||
csrInfo: any;
|
csrInfo: any;
|
||||||
isTest?: boolean;
|
isTest?: boolean;
|
||||||
privateKeyType?: string;
|
privateKeyType?: string;
|
||||||
|
profile?: string;
|
||||||
}): Promise<CertInfo> {
|
}): Promise<CertInfo> {
|
||||||
const { email, isTest, csrInfo, dnsProvider, domainsVerifyPlan } = options;
|
const { email, isTest, csrInfo, dnsProvider, domainsVerifyPlan, profile } = options;
|
||||||
const client: acme.Client = await this.getAcmeClient(email, isTest);
|
const client: acme.Client = await this.getAcmeClient(email, isTest);
|
||||||
|
|
||||||
let domains = options.domains;
|
let domains = options.domains;
|
||||||
@@ -400,6 +401,7 @@ export class AcmeService {
|
|||||||
return await this.challengeRemoveFn(authz, challenge, keyAuthorization, recordReq, recordRes, dnsProvider, httpUploader);
|
return await this.challengeRemoveFn(authz, challenge, keyAuthorization, recordReq, recordRes, dnsProvider, httpUploader);
|
||||||
},
|
},
|
||||||
signal: this.options.signal,
|
signal: this.options.signal,
|
||||||
|
profile,
|
||||||
});
|
});
|
||||||
|
|
||||||
const crtString = crt.toString();
|
const crtString = crt.toString();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export const EVENT_CERT_APPLY_SUCCESS = "CertApply.success";
|
|||||||
|
|
||||||
export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
||||||
@TaskInput({
|
@TaskInput({
|
||||||
title: "域名",
|
title: "证书域名",
|
||||||
component: {
|
component: {
|
||||||
name: "a-select",
|
name: "a-select",
|
||||||
vModel: "value",
|
vModel: "value",
|
||||||
@@ -67,6 +67,7 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
|||||||
|
|
||||||
@TaskOutput({
|
@TaskOutput({
|
||||||
title: "域名证书",
|
title: "域名证书",
|
||||||
|
type: "cert",
|
||||||
})
|
})
|
||||||
cert?: CertInfo;
|
cert?: CertInfo;
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,10 @@ export class CertReader {
|
|||||||
|
|
||||||
getAllDomains() {
|
getAllDomains() {
|
||||||
const { detail } = this.getCrtDetail();
|
const { detail } = this.getCrtDetail();
|
||||||
const domains = [detail.domains.commonName];
|
const domains = [];
|
||||||
|
if (detail.domains?.commonName) {
|
||||||
|
domains.push(detail.domains.commonName);
|
||||||
|
}
|
||||||
domains.push(...detail.domains.altNames);
|
domains.push(...detail.domains.altNames);
|
||||||
//去重
|
//去重
|
||||||
return uniq(domains);
|
return uniq(domains);
|
||||||
@@ -102,12 +105,23 @@ export class CertReader {
|
|||||||
|
|
||||||
static getMainDomain(crt: string) {
|
static getMainDomain(crt: string) {
|
||||||
const { detail } = CertReader.readCertDetail(crt);
|
const { detail } = CertReader.readCertDetail(crt);
|
||||||
return detail.domains.commonName;
|
return CertReader.getMainDomainFromDetail(detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMainDomain() {
|
getMainDomain() {
|
||||||
const { detail } = this.getCrtDetail();
|
const { detail } = this.getCrtDetail();
|
||||||
return detail.domains.commonName;
|
return CertReader.getMainDomainFromDetail(detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getMainDomainFromDetail(detail: CertificateInfo) {
|
||||||
|
let domain = detail?.domains?.commonName;
|
||||||
|
if (domain == null) {
|
||||||
|
domain = detail?.domains?.altNames?.[0];
|
||||||
|
}
|
||||||
|
if (domain == null) {
|
||||||
|
domain = "unknown";
|
||||||
|
}
|
||||||
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveToFile(type: "crt" | "key" | "pfx" | "der" | "oc" | "one" | "ic" | "jks", filepath?: string) {
|
saveToFile(type: "crt" | "key" | "pfx" | "der" | "oc" | "one" | "ic" | "jks", filepath?: string) {
|
||||||
@@ -179,8 +193,7 @@ export class CertReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildCertFileName(suffix: string, applyTime: any, prefix = "cert") {
|
buildCertFileName(suffix: string, applyTime: any, prefix = "cert") {
|
||||||
const detail = this.getCrtDetail();
|
let domain = this.getMainDomain();
|
||||||
let domain = detail.detail.domains.commonName;
|
|
||||||
domain = domain.replaceAll(".", "_").replaceAll("*", "_");
|
domain = domain.replaceAll(".", "_").replaceAll("*", "_");
|
||||||
const timeStr = dayjs(applyTime).format("YYYYMMDDHHmmss");
|
const timeStr = dayjs(applyTime).format("YYYYMMDDHHmmss");
|
||||||
return `${prefix}_${domain}_${timeStr}.${suffix}`;
|
return `${prefix}_${domain}_${timeStr}.${suffix}`;
|
||||||
@@ -188,7 +201,14 @@ export class CertReader {
|
|||||||
|
|
||||||
buildCertName() {
|
buildCertName() {
|
||||||
let domain = this.getMainDomain();
|
let domain = this.getMainDomain();
|
||||||
domain = domain.replaceAll("*", "_").replaceAll("*", "_");
|
domain = domain.replaceAll(".", "_").replaceAll("*", "_");
|
||||||
return `${domain}_${dayjs().format("YYYYMMDDHHmmssSSS")}`;
|
return `${domain}_${dayjs().format("YYYYMMDDHHmmssSSS")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static appendTimeSuffix(name?: string) {
|
||||||
|
if (name == null) {
|
||||||
|
name = "certd";
|
||||||
|
}
|
||||||
|
return name + "_" + dayjs().format("YYYYMMDDHHmmssSSS");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ export class CertApplyUploadPlugin extends CertApplyBaseConvertPlugin {
|
|||||||
|
|
||||||
@TaskOutput({
|
@TaskOutput({
|
||||||
title: "证书MD5",
|
title: "证书MD5",
|
||||||
|
type: "certMd5",
|
||||||
})
|
})
|
||||||
certMd5?: string;
|
certMd5?: string;
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { CancelError, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
import { CancelError, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||||
import { utils } from "@certd/basic";
|
import { utils } from "@certd/basic";
|
||||||
|
|
||||||
import type { CertInfo, CnameVerifyPlan, DomainsVerifyPlan, HttpVerifyPlan, PrivateKeyType, SSLProvider } from "./acme.js";
|
import { AcmeService, CertInfo, DomainsVerifyPlan, DomainVerifyPlan, PrivateKeyType, SSLProvider } from "./acme.js";
|
||||||
import { AcmeService } from "./acme.js";
|
|
||||||
import * as _ from "lodash-es";
|
import * as _ from "lodash-es";
|
||||||
import { createDnsProvider, DnsProviderContext, IDnsProvider, ISubDomainsGetter } from "../../dns-provider/index.js";
|
import { createDnsProvider, DnsProviderContext, DnsVerifier, DomainVerifiers, HttpVerifier, IDnsProvider, IDomainVerifierGetter, ISubDomainsGetter } from "../../dns-provider/index.js";
|
||||||
import { CertReader } from "./cert-reader.js";
|
import { CertReader } from "./cert-reader.js";
|
||||||
import { CertApplyBasePlugin } from "./base.js";
|
import { CertApplyBasePlugin } from "./base.js";
|
||||||
import { GoogleClient } from "../../libs/google.js";
|
import { GoogleClient } from "../../libs/google.js";
|
||||||
import { EabAccess } from "../../access";
|
import { EabAccess } from "../../access";
|
||||||
import { DomainParser } from "../../dns-provider/domain-parser.js";
|
import { DomainParser } from "../../dns-provider/domain-parser.js";
|
||||||
import { ossClientFactory } from "@certd/plugin-lib";
|
import { ossClientFactory } from "@certd/plugin-lib";
|
||||||
|
|
||||||
export * from "./base.js";
|
export * from "./base.js";
|
||||||
export type { CertInfo };
|
export type { CertInfo };
|
||||||
export * from "./cert-reader.js";
|
export * from "./cert-reader.js";
|
||||||
@@ -65,12 +65,17 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
{ value: "dns", label: "DNS直接验证" },
|
{ value: "dns", label: "DNS直接验证" },
|
||||||
{ value: "cname", label: "CNAME代理验证" },
|
{ value: "cname", label: "CNAME代理验证" },
|
||||||
{ value: "http", label: "HTTP文件验证" },
|
{ value: "http", label: "HTTP文件验证" },
|
||||||
|
{ value: "dnses", label: "多DNS提供商" },
|
||||||
|
{ value: "auto", label: "自动匹配" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
required: true,
|
required: true,
|
||||||
helper: `1. <b>DNS直接验证</b>:域名dns解析是在阿里云/腾讯云/华为云/CF/NameSilo/西数/火山/dns.la/京东云/51dns的,选它
|
helper: `1. <b>DNS直接验证</b>:域名dns解析是在阿里云/腾讯云/华为云/CF/NameSilo/西数/火山/dns.la/京东云/51dns的,选它
|
||||||
2. <b>CNAME代理验证</b>:支持任何注册商的域名,第一次需要手动添加CNAME记录(建议将DNS服务器修改为阿里云/腾讯云的,然后使用DNS直接验证)
|
2. <b>CNAME代理验证</b>:支持任何注册商的域名,第一次需要手动添加[CNAME记录](#/certd/cname/record)(建议将DNS服务器修改为阿里云/腾讯云的,然后使用DNS直接验证)
|
||||||
3. <b>HTTP文件验证</b>:不支持泛域名,需要配置网站文件上传`,
|
3. <b>HTTP文件验证</b>:不支持泛域名,需要配置网站文件上传
|
||||||
|
4. <b>多DNS提供商</b>:每个域名可以选择独立的DNS提供商
|
||||||
|
5. <b>自动匹配</b>:需要在[域名管理](#/certd/cert/domain)中事先配置好校验方式
|
||||||
|
`,
|
||||||
})
|
})
|
||||||
challengeType!: string;
|
challengeType!: string;
|
||||||
|
|
||||||
@@ -159,13 +164,15 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
show: ctx.compute(({form})=>{
|
show: ctx.compute(({form})=>{
|
||||||
return form.challengeType === 'cname' || form.challengeType === 'http'
|
return form.challengeType === 'cname' || form.challengeType === 'http' || form.challengeType === 'dnses'
|
||||||
}),
|
}),
|
||||||
helper: ctx.compute(({form})=>{
|
helper: ctx.compute(({form})=>{
|
||||||
if(form.challengeType === 'cname' ){
|
if(form.challengeType === 'cname' ){
|
||||||
return '请按照上面的提示,给要申请证书的域名添加CNAME记录,添加后,点击验证,验证成功后不要删除记录,申请和续期证书会一直用它'
|
return '请按照上面的提示,给要申请证书的域名添加CNAME记录,添加后,点击验证,验证成功后不要删除记录,申请和续期证书会一直用它'
|
||||||
}else if (form.challengeType === 'http'){
|
}else if (form.challengeType === 'http'){
|
||||||
return '请按照上面的提示,给每个域名设置文件上传配置,证书申请过程中会上传校验文件到网站根目录下'
|
return '请按照上面的提示,给每个域名设置文件上传配置,证书申请过程中会上传校验文件到网站根目录下'
|
||||||
|
}else if (form.challengeType === 'http'){
|
||||||
|
return '给每个域名单独配置dns提供商'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -248,6 +255,30 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
})
|
})
|
||||||
privateKeyType!: PrivateKeyType;
|
privateKeyType!: PrivateKeyType;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: "证书配置",
|
||||||
|
value: "classic",
|
||||||
|
component: {
|
||||||
|
name: "a-select",
|
||||||
|
vModel: "value",
|
||||||
|
options: [
|
||||||
|
{ value: "classic", label: "经典(classic)" },
|
||||||
|
{ value: "tlsserver", label: "TLS服务器(tlsserver)" },
|
||||||
|
{ value: "shortlived", label: "短暂的(shortlived)" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
helper: "如无特殊需求,默认即可",
|
||||||
|
required: false,
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show: ctx.compute(({form})=>{
|
||||||
|
return form.sslProvider === 'letsencrypt'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
certProfile!: string;
|
||||||
|
|
||||||
@TaskInput({
|
@TaskInput({
|
||||||
title: "使用代理",
|
title: "使用代理",
|
||||||
value: false,
|
value: false,
|
||||||
@@ -297,13 +328,14 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
name: "a-input-number",
|
name: "a-input-number",
|
||||||
vModel: "value",
|
vModel: "value",
|
||||||
},
|
},
|
||||||
helper: "等待解析生效时长(秒)",
|
helper: "等待解析生效时长(秒),如果使用CNAME方式校验,本地验证失败,可以尝试延长此时间(比如5-10分钟)",
|
||||||
})
|
})
|
||||||
waitDnsDiffuseTime = 30;
|
waitDnsDiffuseTime = 30;
|
||||||
|
|
||||||
acme!: AcmeService;
|
acme!: AcmeService;
|
||||||
|
|
||||||
eab!: EabAccess;
|
eab!: EabAccess;
|
||||||
|
|
||||||
async onInit() {
|
async onInit() {
|
||||||
let eab: EabAccess = null;
|
let eab: EabAccess = null;
|
||||||
|
|
||||||
@@ -378,8 +410,10 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
|
|
||||||
let dnsProvider: IDnsProvider = null;
|
let dnsProvider: IDnsProvider = null;
|
||||||
let domainsVerifyPlan: DomainsVerifyPlan = null;
|
let domainsVerifyPlan: DomainsVerifyPlan = null;
|
||||||
if (this.challengeType === "cname" || this.challengeType === "http") {
|
if (this.challengeType === "cname" || this.challengeType === "http" || this.challengeType === "dnses") {
|
||||||
domainsVerifyPlan = await this.createDomainsVerifyPlan();
|
domainsVerifyPlan = await this.createDomainsVerifyPlan(domains, this.domainsVerifyPlan);
|
||||||
|
} else if (this.challengeType === "auto") {
|
||||||
|
domainsVerifyPlan = await this.createDomainsVerifyPlanByAuto(domains);
|
||||||
} else {
|
} else {
|
||||||
const dnsProviderType = this.dnsProviderType;
|
const dnsProviderType = this.dnsProviderType;
|
||||||
const access = await this.getAccess(this.dnsProviderAccess);
|
const access = await this.getAccess(this.dnsProviderAccess);
|
||||||
@@ -395,6 +429,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
csrInfo,
|
csrInfo,
|
||||||
isTest: false,
|
isTest: false,
|
||||||
privateKeyType: this.privateKeyType,
|
privateKeyType: this.privateKeyType,
|
||||||
|
profile: this.certProfile,
|
||||||
});
|
});
|
||||||
|
|
||||||
const certInfo = this.formatCerts(cert);
|
const certInfo = this.formatCerts(cert);
|
||||||
@@ -414,73 +449,126 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
|
|
||||||
async createDnsProvider(dnsProviderType: string, dnsProviderAccess: any): Promise<IDnsProvider> {
|
async createDnsProvider(dnsProviderType: string, dnsProviderAccess: any): Promise<IDnsProvider> {
|
||||||
const domainParser = this.acme.options.domainParser;
|
const domainParser = this.acme.options.domainParser;
|
||||||
const context: DnsProviderContext = { access: dnsProviderAccess, logger: this.logger, http: this.ctx.http, utils, domainParser };
|
const context: DnsProviderContext = {
|
||||||
|
access: dnsProviderAccess,
|
||||||
|
logger: this.logger,
|
||||||
|
http: this.ctx.http,
|
||||||
|
utils,
|
||||||
|
domainParser,
|
||||||
|
};
|
||||||
return await createDnsProvider({
|
return await createDnsProvider({
|
||||||
dnsProviderType,
|
dnsProviderType,
|
||||||
context,
|
context,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async createDomainsVerifyPlan(): Promise<DomainsVerifyPlan> {
|
async createDomainsVerifyPlan(domains: string[], verifyPlanSetting: DomainsVerifyPlanInput): Promise<DomainsVerifyPlan> {
|
||||||
const plan: DomainsVerifyPlan = {};
|
const plan: DomainsVerifyPlan = {};
|
||||||
for (const domain in this.domainsVerifyPlan) {
|
|
||||||
const domainVerifyPlan = this.domainsVerifyPlan[domain];
|
const domainParser = this.acme.options.domainParser;
|
||||||
let dnsProvider = null;
|
for (const fullDomain of domains) {
|
||||||
const cnameVerifyPlan: Record<string, CnameVerifyPlan> = {};
|
const domain = fullDomain.replaceAll("*.", "");
|
||||||
const httpVerifyPlan: Record<string, HttpVerifyPlan> = {};
|
const mainDomain = await domainParser.parse(domain);
|
||||||
if (domainVerifyPlan.type === "dns") {
|
const planSetting: DomainVerifyPlanInput = verifyPlanSetting[mainDomain];
|
||||||
const access = await this.getAccess(domainVerifyPlan.dnsProviderAccessId);
|
if (planSetting.type === "dns") {
|
||||||
dnsProvider = await this.createDnsProvider(domainVerifyPlan.dnsProviderType, access);
|
plan[domain] = await this.createDnsDomainVerifyPlan(planSetting, domain, mainDomain);
|
||||||
} else if (domainVerifyPlan.type === "cname") {
|
} else if (planSetting.type === "cname") {
|
||||||
for (const key in domainVerifyPlan.cnameVerifyPlan) {
|
plan[domain] = await this.createCnameDomainVerifyPlan(domain, mainDomain);
|
||||||
const cnameRecord = await this.ctx.cnameProxyService.getByDomain(key);
|
} else if (planSetting.type === "http") {
|
||||||
let dnsProvider = cnameRecord.commonDnsProvider;
|
plan[domain] = await this.createHttpDomainVerifyPlan(planSetting.httpVerifyPlan[domain], domain, mainDomain);
|
||||||
if (cnameRecord.cnameProvider.id > 0) {
|
|
||||||
dnsProvider = await this.createDnsProvider(cnameRecord.cnameProvider.dnsProviderType, cnameRecord.cnameProvider.access);
|
|
||||||
}
|
|
||||||
cnameVerifyPlan[key] = {
|
|
||||||
type: "cname",
|
|
||||||
domain: cnameRecord.cnameProvider.domain,
|
|
||||||
fullRecord: cnameRecord.recordValue,
|
|
||||||
dnsProvider,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else if (domainVerifyPlan.type === "http") {
|
|
||||||
const httpUploaderContext = {
|
|
||||||
accessService: this.ctx.accessService,
|
|
||||||
logger: this.logger,
|
|
||||||
utils,
|
|
||||||
};
|
|
||||||
for (const key in domainVerifyPlan.httpVerifyPlan) {
|
|
||||||
const httpRecord = domainVerifyPlan.httpVerifyPlan[key];
|
|
||||||
const access = await this.getAccess(httpRecord.httpUploaderAccess);
|
|
||||||
let rootDir = httpRecord.httpUploadRootDir;
|
|
||||||
if (!rootDir.endsWith("/") && !rootDir.endsWith("\\")) {
|
|
||||||
rootDir = rootDir + "/";
|
|
||||||
}
|
|
||||||
this.logger.info("上传方式", httpRecord.httpUploaderType);
|
|
||||||
const httpUploader = await ossClientFactory.createOssClientByType(httpRecord.httpUploaderType, {
|
|
||||||
access,
|
|
||||||
rootDir: rootDir,
|
|
||||||
ctx: httpUploaderContext,
|
|
||||||
});
|
|
||||||
httpVerifyPlan[key] = {
|
|
||||||
type: "http",
|
|
||||||
domain: key,
|
|
||||||
httpUploader,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
plan[domain] = {
|
|
||||||
domain,
|
|
||||||
type: domainVerifyPlan.type,
|
|
||||||
dnsProvider,
|
|
||||||
cnameVerifyPlan,
|
|
||||||
httpVerifyPlan,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return plan;
|
return plan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async createDomainsVerifyPlanByAuto(domains: string[]) {
|
||||||
|
//从数据库里面自动选择校验方式
|
||||||
|
// domain list
|
||||||
|
const domainList = new Set<string>();
|
||||||
|
//整理域名
|
||||||
|
for (let domain of domains) {
|
||||||
|
domain = domain.replaceAll("*.", "");
|
||||||
|
domainList.add(domain);
|
||||||
|
}
|
||||||
|
const domainVerifierGetter: IDomainVerifierGetter = await this.ctx.serviceGetter.get("domainVerifierGetter");
|
||||||
|
|
||||||
|
const verifiers: DomainVerifiers = await domainVerifierGetter.getVerifiers([...domainList]);
|
||||||
|
|
||||||
|
const plan: DomainsVerifyPlan = {};
|
||||||
|
|
||||||
|
for (const domain in verifiers) {
|
||||||
|
const verifier = verifiers[domain];
|
||||||
|
if (verifier.type === "dns") {
|
||||||
|
plan[domain] = await this.createDnsDomainVerifyPlan(verifier.dns, domain, verifier.mainDomain);
|
||||||
|
} else if (verifier.type === "cname") {
|
||||||
|
plan[domain] = await this.createCnameDomainVerifyPlan(domain, verifier.mainDomain);
|
||||||
|
} else if (verifier.type === "http") {
|
||||||
|
plan[domain] = await this.createHttpDomainVerifyPlan(verifier.http, domain, verifier.mainDomain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return plan;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createDnsDomainVerifyPlan(planSetting: DnsVerifier, domain: string, mainDomain: string): Promise<DomainVerifyPlan> {
|
||||||
|
const access = await this.getAccess(planSetting.dnsProviderAccessId);
|
||||||
|
return {
|
||||||
|
type: "dns",
|
||||||
|
mainDomain,
|
||||||
|
domain,
|
||||||
|
dnsProvider: await this.createDnsProvider(planSetting.dnsProviderType, access),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createHttpDomainVerifyPlan(httpSetting: HttpVerifier, domain: string, mainDomain: string): Promise<DomainVerifyPlan> {
|
||||||
|
const httpUploaderContext = {
|
||||||
|
accessService: this.ctx.accessService,
|
||||||
|
logger: this.logger,
|
||||||
|
utils,
|
||||||
|
};
|
||||||
|
|
||||||
|
const access = await this.getAccess(httpSetting.httpUploaderAccess);
|
||||||
|
let rootDir = httpSetting.httpUploadRootDir;
|
||||||
|
if (!rootDir.endsWith("/") && !rootDir.endsWith("\\")) {
|
||||||
|
rootDir = rootDir + "/";
|
||||||
|
}
|
||||||
|
this.logger.info("上传方式", httpSetting.httpUploaderType);
|
||||||
|
const httpUploader = await ossClientFactory.createOssClientByType(httpSetting.httpUploaderType, {
|
||||||
|
access,
|
||||||
|
rootDir: rootDir,
|
||||||
|
ctx: httpUploaderContext,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
type: "http",
|
||||||
|
domain,
|
||||||
|
mainDomain,
|
||||||
|
httpVerifyPlan: {
|
||||||
|
type: "http",
|
||||||
|
domain,
|
||||||
|
httpUploader,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createCnameDomainVerifyPlan(domain: string, mainDomain: string): Promise<DomainVerifyPlan> {
|
||||||
|
const cnameRecord = await this.ctx.cnameProxyService.getByDomain(domain);
|
||||||
|
if (cnameRecord == null) {
|
||||||
|
throw new Error(`请先配置${domain}的CNAME记录,并通过校验`);
|
||||||
|
}
|
||||||
|
let dnsProvider = cnameRecord.commonDnsProvider;
|
||||||
|
if (cnameRecord.cnameProvider.id > 0) {
|
||||||
|
dnsProvider = await this.createDnsProvider(cnameRecord.cnameProvider.dnsProviderType, cnameRecord.cnameProvider.access);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: "cname",
|
||||||
|
domain,
|
||||||
|
mainDomain,
|
||||||
|
cnameVerifyPlan: {
|
||||||
|
domain: cnameRecord.cnameProvider.domain,
|
||||||
|
fullRecord: cnameRecord.recordValue,
|
||||||
|
dnsProvider,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new CertApplyPlugin();
|
new CertApplyPlugin();
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ export { EVENT_CERT_APPLY_SUCCESS } from "./cert-plugin/base-convert.js";
|
|||||||
export * from "./cert-plugin/index.js";
|
export * from "./cert-plugin/index.js";
|
||||||
export * from "./cert-plugin/lego/index.js";
|
export * from "./cert-plugin/lego/index.js";
|
||||||
export * from "./cert-plugin/custom/index.js";
|
export * from "./cert-plugin/custom/index.js";
|
||||||
export const CertApplyPluginNames = ["CertApply", "CertApplyLego", "CertApplyUpload"];
|
export const CertApplyPluginNames = [":cert:"];
|
||||||
|
|||||||
@@ -3,6 +3,68 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 执行windows nginx命令时,改为return code判断是否执行成功 ([b37cffd](https://github.com/certd/certd/commit/b37cffd704cd08b8bdd68a6e284706eabe59e78d))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持部署到阿里云vod ([98da4e1](https://github.com/certd/certd/commit/98da4e1791ed8bb21daf2a9914fda875d14633c9))
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 腾讯云授权支持设置是否国际站,部署到EO插件支持国际站 ([5cd3968](https://github.com/certd/certd/commit/5cd3968929acef333cf30d3b20cf21cea6c82c5f))
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持s3 access做测试 ([f00aeac](https://github.com/certd/certd/commit/f00aeacb8b5c81f0bafa4c1b76723dec2b6b7784))
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复阿里云新加坡clb无法部署证书的bug ([3e84e11](https://github.com/certd/certd/commit/3e84e116e863b54c6b4d7db160af372dacc5857f))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化阿里云nlb支持部署扩展证书 ([9cbdfda](https://github.com/certd/certd/commit/9cbdfda829b231733d54c66c5024d46e6fc11af3))
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* aliyun alb支持部署扩展证书 ([2a19b61](https://github.com/certd/certd/commit/2a19b61b7a78620c06396c2cc37cc77d738b6d12))
|
||||||
|
|
||||||
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/plugin-lib
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/plugin-lib",
|
"name": "@certd/plugin-lib",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.35.0",
|
"version": "1.36.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -17,11 +17,12 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alicloud/openapi-client": "^0.4.14",
|
"@alicloud/openapi-client": "^0.4.14",
|
||||||
|
"@alicloud/openapi-util": "^0.3.2",
|
||||||
"@alicloud/pop-core": "^1.7.10",
|
"@alicloud/pop-core": "^1.7.10",
|
||||||
"@alicloud/tea-util": "^1.4.10",
|
"@alicloud/tea-util": "^1.4.10",
|
||||||
"@aws-sdk/client-s3": "^3.787.0",
|
"@aws-sdk/client-s3": "^3.787.0",
|
||||||
"@certd/basic": "^1.35.0",
|
"@certd/basic": "^1.36.5",
|
||||||
"@certd/pipeline": "^1.35.0",
|
"@certd/pipeline": "^1.36.5",
|
||||||
"@kubernetes/client-node": "0.21.0",
|
"@kubernetes/client-node": "0.21.0",
|
||||||
"ali-oss": "^6.22.0",
|
"ali-oss": "^6.22.0",
|
||||||
"basic-ftp": "^5.0.5",
|
"basic-ftp": "^5.0.5",
|
||||||
@@ -52,5 +53,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "ab3a3156f24d7fc70f8a907c5f6fc754413a89d6"
|
"gitHead": "c2a95a13fe6edf05ea0f72f5f7c76f9eea3ab0bd"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
|
import { AccessInput, BaseAccess, IsAccess } from "@certd/pipeline";
|
||||||
import { ILogger } from "@certd/basic";
|
import { ILogger } from "@certd/basic";
|
||||||
|
|
||||||
export type AliyunClientV2Req = {
|
export type AliyunClientV2Req = {
|
||||||
action: string;
|
action: string;
|
||||||
version: string;
|
version: string;
|
||||||
@@ -54,7 +53,7 @@ export class AliyunClientV2 {
|
|||||||
|
|
||||||
const $OpenApi = await import("@alicloud/openapi-client");
|
const $OpenApi = await import("@alicloud/openapi-client");
|
||||||
const $Util = await import("@alicloud/tea-util");
|
const $Util = await import("@alicloud/tea-util");
|
||||||
|
const OpenApiUtil = await import("@alicloud/openapi-util");
|
||||||
const params = new $OpenApi.Params({
|
const params = new $OpenApi.Params({
|
||||||
// 接口名称
|
// 接口名称
|
||||||
action: req.action,
|
action: req.action,
|
||||||
@@ -74,6 +73,10 @@ export class AliyunClientV2 {
|
|||||||
bodyType: "json",
|
bodyType: "json",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (req.data?.query) {
|
||||||
|
//@ts-ignore
|
||||||
|
req.data.query = OpenApiUtil.default.default.query(req.data.query);
|
||||||
|
}
|
||||||
const runtime = new $Util.RuntimeOptions({});
|
const runtime = new $Util.RuntimeOptions({});
|
||||||
const request = new $OpenApi.OpenApiRequest(req.data);
|
const request = new $OpenApi.OpenApiRequest(req.data);
|
||||||
// 复制代码运行请自行打印 API 的返回值
|
// 复制代码运行请自行打印 API 的返回值
|
||||||
|
|||||||
@@ -29,12 +29,14 @@ export type AliyunSslUploadCertReq = {
|
|||||||
cert: AliyunCertInfo;
|
cert: AliyunCertInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CasCertInfo = { certId: number; certName: string; certIdentifier: string };
|
export type CasCertInfo = { certId: number; certName: string; certIdentifier: string; notAfter: number; casRegion: string };
|
||||||
|
|
||||||
export class AliyunSslClient {
|
export class AliyunSslClient {
|
||||||
opts: AliyunSslClientOpts;
|
opts: AliyunSslClientOpts;
|
||||||
|
logger: ILogger;
|
||||||
constructor(opts: AliyunSslClientOpts) {
|
constructor(opts: AliyunSslClientOpts) {
|
||||||
this.opts = opts;
|
this.opts = opts;
|
||||||
|
this.logger = opts.logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkRet(ret: any) {
|
checkRet(ret: any) {
|
||||||
@@ -68,6 +70,8 @@ export class AliyunSslClient {
|
|||||||
certId: certId,
|
certId: certId,
|
||||||
certName: res.Name,
|
certName: res.Name,
|
||||||
certIdentifier: res.CertIdentifier,
|
certIdentifier: res.CertIdentifier,
|
||||||
|
notAfter: res.NotAfter,
|
||||||
|
casRegion: this.getCasRegionFromEndpoint(this.opts.endpoint),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,4 +152,24 @@ export class AliyunSslClient {
|
|||||||
this.checkRet(res);
|
this.checkRet(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteCert(certId: any) {
|
||||||
|
await this.doRequest("DeleteUserCertificate", { CertId: certId }, { method: "POST" });
|
||||||
|
}
|
||||||
|
|
||||||
|
getCasRegionFromEndpoint(endpoint: string) {
|
||||||
|
if (!endpoint) {
|
||||||
|
return "cn-hangzhou";
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* {value: 'cas.aliyuncs.com', label: '中国大陆'},
|
||||||
|
* {value: 'cas.ap-southeast-1.aliyuncs.com', label: '新加坡'},
|
||||||
|
* {value: 'cas.eu-central-1.aliyuncs.com', label: '德国(法兰克福)'},
|
||||||
|
*/
|
||||||
|
const region = endpoint.replace(".aliyuncs.com", "").replace("cas.", "");
|
||||||
|
if (region === "cas") {
|
||||||
|
return "cn-hangzhou";
|
||||||
|
}
|
||||||
|
return region;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export function createCertDomainGetterInputDefine(opts?: { certInputKey?: string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
template:false,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
opts?.props
|
opts?.props
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ export default class S3OssClientImpl extends BaseOssClient<S3Access> {
|
|||||||
Prefix: dirKey, // The name of the object. For example, 'sample_upload.txt'.
|
Prefix: dirKey, // The name of the object. For example, 'sample_upload.txt'.
|
||||||
};
|
};
|
||||||
const res = await this.client.send(new ListObjectsCommand({ ...params }));
|
const res = await this.client.send(new ListObjectsCommand({ ...params }));
|
||||||
|
if (!res.Contents) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
return res.Contents.map(item => {
|
return res.Contents.map(item => {
|
||||||
return {
|
return {
|
||||||
path: item.Key,
|
path: item.Key,
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { AccessInput, BaseAccess, IsAccess } from "@certd/pipeline";
|
import { AccessInput, BaseAccess, IsAccess } from "@certd/pipeline";
|
||||||
|
import { ossClientFactory } from "../oss/index.js";
|
||||||
|
import S3OssClientImpl from "../oss/impls/s3.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 这个注解将注册一个授权配置
|
* 这个注解将注册一个授权配置
|
||||||
@@ -82,6 +84,32 @@ export class S3Access extends BaseAccess {
|
|||||||
required: true,
|
required: true,
|
||||||
})
|
})
|
||||||
bucket!: string;
|
bucket!: string;
|
||||||
|
|
||||||
|
@AccessInput({
|
||||||
|
title: "测试",
|
||||||
|
component: {
|
||||||
|
name: "api-test",
|
||||||
|
action: "TestRequest",
|
||||||
|
},
|
||||||
|
helper: "点击测试接口是否正常",
|
||||||
|
})
|
||||||
|
testRequest = true;
|
||||||
|
|
||||||
|
async onTestRequest() {
|
||||||
|
const client: S3OssClientImpl = await ossClientFactory.createOssClientByType("s3", {
|
||||||
|
access: this,
|
||||||
|
rootDir: "",
|
||||||
|
ctx: {
|
||||||
|
accessService: this.ctx.accessService,
|
||||||
|
logger: this.ctx.logger,
|
||||||
|
utils: this.ctx.utils,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.listDir("/");
|
||||||
|
|
||||||
|
return "ok";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new S3Access();
|
new S3Access();
|
||||||
|
|||||||
@@ -204,9 +204,18 @@ export class AsyncSsh2Client {
|
|||||||
stream
|
stream
|
||||||
.on("close", (code: any, signal: any) => {
|
.on("close", (code: any, signal: any) => {
|
||||||
this.logger.info(`[${this.connConf.host}][close]:code:${code}`);
|
this.logger.info(`[${this.connConf.host}][close]:code:${code}`);
|
||||||
if (opts.throwOnStdErr == null && this.windows) {
|
/**
|
||||||
opts.throwOnStdErr = true;
|
* ]pipeline 执行命令:[10.123.0.2][exec]:cd /d D:\nginx-1.27.5 && D:\nginx-1.27.5\nginx.exe -t && D:\nginx-1.27.5\nginx.exe -s reload
|
||||||
}
|
* [2025-07-09T10:24:11.219] [ERROR]pipeline - [10. 123.0. 2][error]: nginx: the configuration file D: \nginx-1.27. 5/conf/nginx. conf syntax is ok
|
||||||
|
* [2025-07-09T10:24:11.231] [ERROR][10. 123. 0. 2] [error]: nginx: configuration file D: \nginx-1.27.5/conf/nginx.conf test is successful
|
||||||
|
* pipeline-
|
||||||
|
* [2025-07-09T10:24:11.473] [INFO]pipeline -[10.123.0.2][close]:code:0
|
||||||
|
* [2025-07-09T10:24:11.473][ERRoR] pipeline- [step][主机一执行远程主机脚本命令]<id:53hyarN3yvmbijNuMiNAt>: [Eror: nginx: the configuration fileD:\nginx-1.27.5/conf/nginx.conf syntax is ok
|
||||||
|
//需要忽略windows的错误
|
||||||
|
*/
|
||||||
|
// if (opts.throwOnStdErr == null && this.windows) {
|
||||||
|
// opts.throwOnStdErr = true;
|
||||||
|
// }
|
||||||
if (opts.throwOnStdErr && hasErrorLog) {
|
if (opts.throwOnStdErr && hasErrorLog) {
|
||||||
reject(new Error(data));
|
reject(new Error(data));
|
||||||
}
|
}
|
||||||
@@ -482,9 +491,9 @@ export class SshClient {
|
|||||||
* Set-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\cmd.exe"
|
* Set-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\cmd.exe"
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
async exec(options: { connectConf: SshAccess; script: string | Array<string>; env?: any }): Promise<string> {
|
async exec(options: { connectConf: SshAccess; script: string | Array<string>; env?: any; throwOnStdErr?: boolean; stopOnError?: boolean }): Promise<string> {
|
||||||
let { script } = options;
|
let { script } = options;
|
||||||
const { connectConf } = options;
|
const { connectConf, throwOnStdErr } = options;
|
||||||
|
|
||||||
// this.logger.info('命令:', script);
|
// this.logger.info('命令:', script);
|
||||||
return await this._call({
|
return await this._call({
|
||||||
@@ -497,6 +506,10 @@ export class SshClient {
|
|||||||
isWinCmd = await this.isCmd(conn);
|
isWinCmd = await this.isCmd(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isLinux && options.stopOnError !== false) {
|
||||||
|
script = "set -e\n" + script;
|
||||||
|
}
|
||||||
|
|
||||||
if (options.env) {
|
if (options.env) {
|
||||||
for (const key in options.env) {
|
for (const key in options.env) {
|
||||||
if (isLinux) {
|
if (isLinux) {
|
||||||
@@ -529,7 +542,8 @@ export class SshClient {
|
|||||||
script = envScripts.join(newLine) + newLine + script;
|
script = envScripts.join(newLine) + newLine + script;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return await conn.exec(script as string, {});
|
|
||||||
|
return await conn.exec(script as string, { throwOnStdErr });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
|
|||||||
export class TencentAccess extends BaseAccess {
|
export class TencentAccess extends BaseAccess {
|
||||||
@AccessInput({
|
@AccessInput({
|
||||||
title: "secretId",
|
title: "secretId",
|
||||||
helper:
|
helper: "使用对应的插件需要有对应的权限,比如上传证书,需要证书管理权限;部署到clb需要clb相关权限\n前往[密钥管理](https://console.cloud.tencent.com/cam/capi)进行创建",
|
||||||
"使用对应的插件需要有对应的权限,比如上传证书,需要证书管理权限;部署到clb需要clb相关权限\n前往[密钥管理](https://console.cloud.tencent.com/cam/capi)进行创建",
|
|
||||||
component: {
|
component: {
|
||||||
placeholder: "secretId",
|
placeholder: "secretId",
|
||||||
},
|
},
|
||||||
@@ -25,4 +24,29 @@ export class TencentAccess extends BaseAccess {
|
|||||||
rules: [{ required: true, message: "该项必填" }],
|
rules: [{ required: true, message: "该项必填" }],
|
||||||
})
|
})
|
||||||
secretKey = "";
|
secretKey = "";
|
||||||
|
|
||||||
|
@AccessInput({
|
||||||
|
title: "站点类型",
|
||||||
|
value: "cn",
|
||||||
|
component: {
|
||||||
|
name: "a-select",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: "国内站",
|
||||||
|
value: "cn",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "国际站",
|
||||||
|
value: "intl",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
encrypt: false,
|
||||||
|
rules: [{ required: true, message: "该项必填" }],
|
||||||
|
})
|
||||||
|
accountType: string;
|
||||||
|
|
||||||
|
isIntl() {
|
||||||
|
return this.accountType === "intl";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,100 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/ui-client
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复查看证书对话框翻译错误的bug ([8626b6d](https://github.com/certd/certd/commit/8626b6d9f235c511766f2ae98e0a37f6cebb621c))
|
||||||
|
* 修复translation后分组编辑打不开的bug ([46a1b74](https://github.com/certd/certd/commit/46a1b7479923d2feb2dece202a5932b99981b2cd))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化证书进度条颜色 ([2af91db](https://github.com/certd/certd/commit/2af91dbf2ae36a4ed17c6788bc2a2a79a3bb29f8))
|
||||||
|
* output-selector from参数支持更丰富的过滤规则 ([87853a2](https://github.com/certd/certd/commit/87853a201535f3bfe8505c40f8f5229d82ffcc73))
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复开放接口添加按钮文本显示问题 ([f93ba99](https://github.com/certd/certd/commit/f93ba9970c12680f38eba2a7abd4b72cf3f5b6a6))
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复notification编辑按钮无法打开对话框的bug ([0cea26c](https://github.com/certd/certd/commit/0cea26c6287f52adf273b4a525c37bea8555c68c))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 证书检查支持自定义dns服务器 ([c53bb7c](https://github.com/certd/certd/commit/c53bb7cf677faa32729709ae0c10359db5194d7a))
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复通知和触发器无法编辑的bug ([a2e0951](https://github.com/certd/certd/commit/a2e09510426680eb425c0d7ad337f39d3f052054))
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* 支持模版创建流水线 ([2559f0e](https://github.com/certd/certd/commit/2559f0e822db095d1d26a7f1d517622dce22a5c2))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 阿里云waf cname站点选择支持翻页及域名查询 ([4cf9858](https://github.com/certd/certd/commit/4cf98584dacc5999752732f136246647a2f1f07d))
|
||||||
|
* 模版导入流水线 ([dcc8c56](https://github.com/certd/certd/commit/dcc8c569693432579709ce63656665a76bcf9a44))
|
||||||
|
* 添加用户资料编辑功能 ([7c0f43c](https://github.com/certd/certd/commit/7c0f43c8a3052f73afee3e93c9fcbc43c44ab690))
|
||||||
|
* 优化阿里云waf的日志信息 ([821c6d8](https://github.com/certd/certd/commit/821c6d807d4b3cc5092d09a6282b8cbafb9e7c9f))
|
||||||
|
* 优化中英文翻译与切换 ([acaa8b1](https://github.com/certd/certd/commit/acaa8b173183b4423584ee070e6e332e0ac0eb2d))
|
||||||
|
* 站点IP监控前先同步一下IP ([a080b60](https://github.com/certd/certd/commit/a080b606ab6e289d96b17ef7d2879b4603f889ba))
|
||||||
|
* 支持选择运行策略设置 ([60f055f](https://github.com/certd/certd/commit/60f055f293ce237c21cd9050333dad9609eceac1))
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复邮箱包含.号校验失败的bug ([65dcae7](https://github.com/certd/certd/commit/65dcae79f8faa7a6cb425e10a0fdb6758b0719f3))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 首次打开任务日志查看页面,自动滚动到底部 ([43fee42](https://github.com/certd/certd/commit/43fee42198e8697185b427b1fa3eb79409603393))
|
||||||
|
* 支持批量修改通知和定时 ([e11b3be](https://github.com/certd/certd/commit/e11b3becfd4abe6547e84d09adc38ebd6e1c4b87))
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/ui-client
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复重试次数设置无效的bug ([e2099ac](https://github.com/certd/certd/commit/e2099ac9ca344bc70bfa4219002e9138708973ae))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 授权列表类型颜色优化 ([1e86338](https://github.com/certd/certd/commit/1e863382d3d1a8cc95a1abf51e75bf6eaea3244f))
|
||||||
|
* 支持雨云dns解析以及雨云证书更新 ([43c7a19](https://github.com/certd/certd/commit/43c7a1984926f5d4647760cc134bb0aede3a7b7a))
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 子域名托管帮助链接优化为打开新窗口 ([7c0cdd1](https://github.com/certd/certd/commit/7c0cdd169e2f943e703e433677f2f437d4aa02ee))
|
||||||
|
* history增加触发类型显示 ([7f6070c](https://github.com/certd/certd/commit/7f6070c960ed7bf02add5ab36436de6573f2f1fa))
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化流水线页面,增加下次执行时间、查看证书显示 ([c820315](https://github.com/certd/certd/commit/c8203154094fae3d17198747f49f5f41ddf29a4e))
|
||||||
|
* 站点证书监控支持定时设置,重试次数设置 ([d3c2f8e](https://github.com/certd/certd/commit/d3c2f8eb436e670772d14a54acd6b541c5aa3978))
|
||||||
|
|
||||||
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/ui-client
|
**Note:** Version bump only for package @certd/ui-client
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/ui-client",
|
"name": "@certd/ui-client",
|
||||||
"version": "1.35.0",
|
"version": "1.36.5",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --open",
|
"dev": "vite --open",
|
||||||
@@ -15,7 +15,8 @@
|
|||||||
"serve": "vite preview",
|
"serve": "vite preview",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"pretty-quick": "pretty-quick",
|
"pretty-quick": "pretty-quick",
|
||||||
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/",
|
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue --ext .ts --ext .tsx src/",
|
||||||
|
"format": "prettier --write src",
|
||||||
"upgrade": "yarn upgrade-interactive --latest",
|
"upgrade": "yarn upgrade-interactive --latest",
|
||||||
"tsc": "vue-tsc --noEmit --skipLibCheck",
|
"tsc": "vue-tsc --noEmit --skipLibCheck",
|
||||||
"circle:check": "pnpm dependency-cruise --validate --output-type err-html -f dependency-report.html src",
|
"circle:check": "pnpm dependency-cruise --validate --output-type err-html -f dependency-report.html src",
|
||||||
@@ -30,10 +31,10 @@
|
|||||||
"@aws-sdk/client-s3": "^3.535.0",
|
"@aws-sdk/client-s3": "^3.535.0",
|
||||||
"@aws-sdk/s3-request-presigner": "^3.535.0",
|
"@aws-sdk/s3-request-presigner": "^3.535.0",
|
||||||
"@ctrl/tinycolor": "^4.1.0",
|
"@ctrl/tinycolor": "^4.1.0",
|
||||||
"@fast-crud/fast-crud": "^1.25.8",
|
"@fast-crud/fast-crud": "^1.25.13",
|
||||||
"@fast-crud/fast-extends": "^1.25.8",
|
"@fast-crud/fast-extends": "^1.25.13",
|
||||||
"@fast-crud/ui-antdv4": "^1.25.8",
|
"@fast-crud/ui-antdv4": "^1.25.13",
|
||||||
"@fast-crud/ui-interface": "^1.25.8",
|
"@fast-crud/ui-interface": "^1.25.13",
|
||||||
"@iconify/tailwind": "^1.2.0",
|
"@iconify/tailwind": "^1.2.0",
|
||||||
"@iconify/vue": "^4.1.1",
|
"@iconify/vue": "^4.1.1",
|
||||||
"@manypkg/get-packages": "^2.2.2",
|
"@manypkg/get-packages": "^2.2.2",
|
||||||
@@ -102,8 +103,8 @@
|
|||||||
"zod-defaults": "^0.1.3"
|
"zod-defaults": "^0.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@certd/lib-iframe": "^1.35.0",
|
"@certd/lib-iframe": "^1.36.5",
|
||||||
"@certd/pipeline": "^1.35.0",
|
"@certd/pipeline": "^1.36.5",
|
||||||
"@rollup/plugin-commonjs": "^25.0.7",
|
"@rollup/plugin-commonjs": "^25.0.7",
|
||||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||||
"@types/chai": "^4.3.12",
|
"@types/chai": "^4.3.12",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<AConfigProvider :locale="locale" :theme="tokenTheme">
|
<AConfigProvider :locale="antdvLocale" :theme="tokenTheme">
|
||||||
<FsFormProvider>
|
<FsFormProvider>
|
||||||
<contextHolder />
|
<contextHolder />
|
||||||
<router-view />
|
<router-view />
|
||||||
@@ -8,46 +8,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import zhCN from "ant-design-vue/es/locale/zh_CN";
|
import { computed, provide, ref } from "vue";
|
||||||
import enUS from "ant-design-vue/es/locale/en_US";
|
import { preferences, usePreferences } from "/@/vben/preferences";
|
||||||
import { computed, onMounted, provide, ref } from "vue";
|
|
||||||
import "dayjs/locale/zh-cn";
|
|
||||||
import "dayjs/locale/en";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import { usePreferences, preferences } from "/@/vben/preferences";
|
|
||||||
import { useAntdDesignTokens } from "/@/vben/hooks";
|
import { useAntdDesignTokens } from "/@/vben/hooks";
|
||||||
import { theme } from "ant-design-vue";
|
import { Modal, theme } from "ant-design-vue";
|
||||||
import AConfigProvider from "ant-design-vue/es/config-provider";
|
import AConfigProvider from "ant-design-vue/es/config-provider";
|
||||||
import { Modal } from "ant-design-vue";
|
import { antdvLocale } from "./locales/antdv";
|
||||||
import MaxKBChat from "/@/components/ai/index.vue";
|
import { setI18nLanguage } from "/@/locales";
|
||||||
import { util } from "/@/utils";
|
|
||||||
import { useSettingStore } from "/@/store/settings";
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "App",
|
name: "App",
|
||||||
});
|
});
|
||||||
|
|
||||||
const [modal, contextHolder] = Modal.useModal();
|
const [modal, contextHolder] = Modal.useModal();
|
||||||
provide("modal", modal);
|
provide("modal", modal);
|
||||||
//刷新页面方法
|
|
||||||
const locale = ref(zhCN);
|
|
||||||
async function reload() {}
|
|
||||||
localeChanged("zh-cn");
|
|
||||||
provide("fn:router.reload", reload);
|
|
||||||
provide("fn:locale.changed", localeChanged);
|
|
||||||
//刷新页面方法
|
|
||||||
function localeChanged(value: any) {
|
|
||||||
console.log("locale changed:", value);
|
|
||||||
if (value === "zh-cn") {
|
|
||||||
locale.value = zhCN;
|
|
||||||
dayjs.locale("zh-cn");
|
|
||||||
} else if (value === "en") {
|
|
||||||
locale.value = enUS;
|
|
||||||
dayjs.locale("en");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
localeChanged("zh-cn");
|
|
||||||
provide("fn:router.reload", reload);
|
|
||||||
provide("fn:locale.changed", localeChanged);
|
|
||||||
|
|
||||||
|
const locale = preferences.app.locale;
|
||||||
|
setI18nLanguage(locale);
|
||||||
|
|
||||||
const { isDark } = usePreferences();
|
const { isDark } = usePreferences();
|
||||||
const { tokens } = useAntdDesignTokens();
|
const { tokens } = useAntdDesignTokens();
|
||||||
@@ -65,13 +41,4 @@ const tokenTheme = computed(() => {
|
|||||||
token: tokens,
|
token: tokens,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
//其他初始化
|
|
||||||
// const resourceStore = useResourceStore();
|
|
||||||
// resourceStore.init();
|
|
||||||
// const pageStore = usePageStore();
|
|
||||||
// pageStore.init();
|
|
||||||
// const settingStore = useSettingStore();
|
|
||||||
// settingStore.init();
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ import { cloneDeep, debounce as lodashDebounce } from "lodash-es";
|
|||||||
import { initWorkers } from "./workers";
|
import { initWorkers } from "./workers";
|
||||||
import { importJavascriptContribution, importJsonContribution, importMonacoYaml, importYamlContribution } from "./async-import";
|
import { importJavascriptContribution, importJsonContribution, importMonacoYaml, importYamlContribution } from "./async-import";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "CodeEditor",
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* config:
|
* config:
|
||||||
* value: '', // 编辑器初始文本
|
* value: '', // 编辑器初始文本
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "PiContainer"
|
name: "PiContainer",
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="cron-editor">
|
<div class="cron-editor">
|
||||||
<div class="flex-o">
|
<div class="flex-o">
|
||||||
<cron-light
|
<cron-light :disabled="disabled" :readonly="readonly" :period="period" class="flex-o cron-ant" locale="zh-CN" format="quartz" :model-value="modelValue" @update:model-value="onUpdate" @error="onError" />
|
||||||
:disabled="disabled"
|
|
||||||
:readonly="readonly"
|
|
||||||
:period="period"
|
|
||||||
class="flex-o cron-ant"
|
|
||||||
locale="zh-CN"
|
|
||||||
format="quartz"
|
|
||||||
:model-value="modelValue"
|
|
||||||
@update:model-value="onUpdate"
|
|
||||||
@error="onError"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-5 flex">
|
<div class="mt-5 flex">
|
||||||
<a-input :disabled="true" :readonly="readonly" :value="modelValue" @change="onChange"></a-input>
|
<a-input :disabled="true" :readonly="readonly" :value="modelValue" @change="onChange"></a-input>
|
||||||
<fs-icon icon="ion:close-circle" class="pointer fs-16 ml-5 color-gray" title="清除选择" @click="onClear"></fs-icon>
|
<fs-icon icon="ion:close-circle" class="pointer fs-16 ml-5 color-gray" :title="t('certd.cron.clearTip')" @click="onClear"></fs-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="helper">下次触发时间:{{ nextTime }}</div>
|
<div class="helper">{{ t("certd.cron.nextTrigger") }}:{{ nextTime }}</div>
|
||||||
<div class="fs-helper">{{ errorMessage }}</div>
|
<div class="fs-helper">{{ errorMessage }}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -26,13 +16,18 @@
|
|||||||
import parser from "cron-parser";
|
import parser from "cron-parser";
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
import { getCronNextTimes } from "/@/components/cron-editor/utils";
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "CronEditor"
|
name: "CronEditor",
|
||||||
});
|
});
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue?: string;
|
modelValue?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
|
allowEveryMin?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const period = ref<string>("");
|
const period = ref<string>("");
|
||||||
@@ -58,9 +53,12 @@ const onUpdate = (value: string) => {
|
|||||||
if (arr[0] === "*") {
|
if (arr[0] === "*") {
|
||||||
arr[0] = "0";
|
arr[0] = "0";
|
||||||
}
|
}
|
||||||
if (arr[1] === "*") {
|
if (!props.allowEveryMin) {
|
||||||
arr[1] = "0";
|
if (arr[1] === "*") {
|
||||||
|
arr[1] = "0";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value = arr.join(" ");
|
value = arr.join(" ");
|
||||||
|
|
||||||
emit("update:modelValue", value);
|
emit("update:modelValue", value);
|
||||||
@@ -88,15 +86,15 @@ const onClear = () => {
|
|||||||
|
|
||||||
const nextTime = computed(() => {
|
const nextTime = computed(() => {
|
||||||
if (props.modelValue == null) {
|
if (props.modelValue == null) {
|
||||||
return "请先设置正确的cron表达式";
|
return t("certd.cron.tip");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const interval = parser.parseExpression(props.modelValue);
|
const nextTimes = getCronNextTimes(props.modelValue, 2);
|
||||||
const next = interval.next().getTime();
|
return nextTimes.join(",");
|
||||||
return dayjs(next).format("YYYY-MM-DD HH:mm:ss");
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
return "请先设置正确的cron表达式";
|
return t("certd.cron.tip");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -104,18 +102,22 @@ const nextTime = computed(() => {
|
|||||||
.cron-editor {
|
.cron-editor {
|
||||||
.cron-ant {
|
.cron-ant {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
&* > {
|
&* > {
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcron-select-list {
|
.vcron-select-list {
|
||||||
min-width: 56px;
|
min-width: 56px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcron-select-input {
|
.vcron-select-input {
|
||||||
min-height: 22px;
|
min-height: 22px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcron-select-container {
|
.vcron-select-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
15
packages/ui/certd-client/src/components/cron-editor/utils.ts
Normal file
15
packages/ui/certd-client/src/components/cron-editor/utils.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import parser from "cron-parser";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
export function getCronNextTimes(cron: string, count: number = 1) {
|
||||||
|
if (cron == null) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const nextTimes = [];
|
||||||
|
const interval = parser.parseExpression(cron);
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
const next = interval.next().getTime();
|
||||||
|
nextTimes.push(dayjs(next).format("YYYY-MM-DD HH:mm:ss"));
|
||||||
|
}
|
||||||
|
return nextTimes;
|
||||||
|
}
|
||||||
@@ -76,7 +76,7 @@ export default {
|
|||||||
.text-editable {
|
.text-editable {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
line-height: 34px;
|
line-height: 34px;
|
||||||
|
overflow: hidden;
|
||||||
span.fs-iconify {
|
span.fs-iconify {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
@@ -26,7 +26,9 @@
|
|||||||
import { defineComponent, onMounted, ref } from "vue";
|
import { defineComponent, onMounted, ref } from "vue";
|
||||||
import * as api from "./api";
|
import * as api from "./api";
|
||||||
import { Modal, notification } from "ant-design-vue";
|
import { Modal, notification } from "ant-design-vue";
|
||||||
|
defineOptions({
|
||||||
|
name: "EmailEditor",
|
||||||
|
});
|
||||||
const props = defineProps<{}>();
|
const props = defineProps<{}>();
|
||||||
const VNodes = defineComponent({
|
const VNodes = defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -54,14 +56,15 @@ onMounted(async () => {
|
|||||||
async function addItem() {
|
async function addItem() {
|
||||||
const email = newEmail.value;
|
const email = newEmail.value;
|
||||||
//验证邮箱格式
|
//验证邮箱格式
|
||||||
if (!/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(newEmail.value)) {
|
const regExp =
|
||||||
|
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+\.)+[a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,}))$/;
|
||||||
|
if (!regExp.test(email)) {
|
||||||
notification.error({
|
notification.error({
|
||||||
message: "请填写正确的邮箱地址",
|
message: "请填写正确的邮箱地址",
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
debugger;
|
|
||||||
if (emails.value.find(item => item.value === email)) {
|
if (emails.value.find(item => item.value === email)) {
|
||||||
notification.warning({
|
notification.warning({
|
||||||
message: "此邮箱已存在",
|
message: "此邮箱已存在",
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import dayjs from "dayjs";
|
|||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "ExpiresTimeText"
|
name: "ExpiresTimeText",
|
||||||
});
|
});
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Author: Pedro Oliveira <kanytu@gmail . com>
|
|||||||
.hljs-literal,
|
.hljs-literal,
|
||||||
.hljs-symbol,
|
.hljs-symbol,
|
||||||
.hljs-bullet {
|
.hljs-bullet {
|
||||||
color: #6897BB;
|
color: #6897bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-keyword,
|
.hljs-keyword,
|
||||||
@@ -42,7 +42,7 @@ Author: Pedro Oliveira <kanytu@gmail . com>
|
|||||||
.hljs-string,
|
.hljs-string,
|
||||||
.hljs-attribute,
|
.hljs-attribute,
|
||||||
.hljs-addition {
|
.hljs-addition {
|
||||||
color: #6A8759;
|
color: #6a8759;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-section,
|
.hljs-section,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
|||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
background: #FFFFFF;
|
background: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs,
|
.hljs,
|
||||||
@@ -21,7 +21,7 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
|||||||
.hljs-selector-tag,
|
.hljs-selector-tag,
|
||||||
.hljs-doctag,
|
.hljs-doctag,
|
||||||
.hljs-name {
|
.hljs-name {
|
||||||
color: #00979D;
|
color: #00979d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-built_in,
|
.hljs-built_in,
|
||||||
@@ -29,7 +29,7 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
|||||||
.hljs-bullet,
|
.hljs-bullet,
|
||||||
.hljs-code,
|
.hljs-code,
|
||||||
.hljs-addition {
|
.hljs-addition {
|
||||||
color: #D35400;
|
color: #d35400;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-regexp,
|
.hljs-regexp,
|
||||||
@@ -39,7 +39,7 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
|||||||
.hljs-link,
|
.hljs-link,
|
||||||
.hljs-selector-attr,
|
.hljs-selector-attr,
|
||||||
.hljs-selector-pseudo {
|
.hljs-selector-pseudo {
|
||||||
color: #00979D;
|
color: #00979d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-type,
|
.hljs-type,
|
||||||
@@ -49,7 +49,7 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
|||||||
.hljs-quote,
|
.hljs-quote,
|
||||||
.hljs-template-tag,
|
.hljs-template-tag,
|
||||||
.hljs-deletion {
|
.hljs-deletion {
|
||||||
color: #005C5F;
|
color: #005c5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-title,
|
.hljs-title,
|
||||||
@@ -59,15 +59,15 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hljs-comment {
|
.hljs-comment {
|
||||||
color: rgba(149,165,166,.8);
|
color: rgba(149, 165, 166, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-meta-keyword {
|
.hljs-meta-keyword {
|
||||||
color: #728E00;
|
color: #728e00;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-meta {
|
.hljs-meta {
|
||||||
color: #728E00;
|
color: #728e00;
|
||||||
color: #434f54;
|
color: #434f54;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,9 +80,9 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hljs-function {
|
.hljs-function {
|
||||||
color: #728E00;
|
color: #728e00;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-number {
|
.hljs-number {
|
||||||
color: #8A7B52;
|
color: #8a7b52;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ Brown Paper style from goldblog.com.ua (c) Zaripov Yura <yur4ik7@ukr.net>
|
|||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
background:#b7a68e url(./brown-papersq.png);
|
background: #b7a68e url(./brown-papersq.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-keyword,
|
.hljs-keyword,
|
||||||
.hljs-selector-tag,
|
.hljs-selector-tag,
|
||||||
.hljs-literal {
|
.hljs-literal {
|
||||||
color:#005599;
|
color: #005599;
|
||||||
font-weight:bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs,
|
.hljs,
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ Ported by Fabrício Tavares de Oliveira
|
|||||||
color: #88f;
|
color: #88f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.hljs-keyword,
|
.hljs-keyword,
|
||||||
.hljs-selector-tag,
|
.hljs-selector-tag,
|
||||||
.hljs-title,
|
.hljs-title,
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ Darcula color scheme from the JetBrains family of IDEs
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
.hljs {
|
.hljs {
|
||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
Please use darcula.css instead.
|
Please use darcula.css instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import url('darcula.css');
|
@import url("darcula.css");
|
||||||
|
|||||||
@@ -8,10 +8,9 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
|||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
background: #F0F0F0;
|
background: #f0f0f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Base color: saturation 0; */
|
/* Base color: saturation 0; */
|
||||||
|
|
||||||
.hljs,
|
.hljs,
|
||||||
@@ -32,7 +31,6 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* User color: hue: 0 */
|
/* User color: hue: 0 */
|
||||||
|
|
||||||
.hljs-type,
|
.hljs-type,
|
||||||
@@ -59,14 +57,13 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
|||||||
.hljs-link,
|
.hljs-link,
|
||||||
.hljs-selector-attr,
|
.hljs-selector-attr,
|
||||||
.hljs-selector-pseudo {
|
.hljs-selector-pseudo {
|
||||||
color: #BC6060;
|
color: #bc6060;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Language color: hue: 90; */
|
/* Language color: hue: 90; */
|
||||||
|
|
||||||
.hljs-literal {
|
.hljs-literal {
|
||||||
color: #78A960;
|
color: #78a960;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-built_in,
|
.hljs-built_in,
|
||||||
@@ -76,7 +73,6 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
|||||||
color: #397300;
|
color: #397300;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Meta color: hue: 200 */
|
/* Meta color: hue: 200 */
|
||||||
|
|
||||||
.hljs-meta {
|
.hljs-meta {
|
||||||
@@ -87,7 +83,6 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
|||||||
color: #4d99bf;
|
color: #4d99bf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Misc effects */
|
/* Misc effects */
|
||||||
|
|
||||||
.hljs-emphasis {
|
.hljs-emphasis {
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ Date: 2013-04-02
|
|||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
background: #eee; color: black;
|
background: #eee;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-link,
|
.hljs-link,
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ Google Code style (c) Aahan Krish <geekpanth3r@gmail.com>
|
|||||||
|
|
||||||
.hljs-selector-id,
|
.hljs-selector-id,
|
||||||
.hljs-selector-class {
|
.hljs-selector-class {
|
||||||
color: #9B703F
|
color: #9b703f;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-addition {
|
.hljs-addition {
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ grayscale style (c) MY Sun <simonmysun@gmail.com>
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hljs-regexp {
|
.hljs-regexp {
|
||||||
color: #333;
|
color: #333;
|
||||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAICAYAAADA+m62AAAAPUlEQVQYV2NkQAN37979r6yszIgujiIAU4RNMVwhuiQ6H6wQl3XI4oy4FMHcCJPHcDS6J2A2EqUQpJhohQDexSef15DBCwAAAABJRU5ErkJggg==) repeat;
|
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAICAYAAADA+m62AAAAPUlEQVQYV2NkQAN37979r6yszIgujiIAU4RNMVwhuiQ6H6wQl3XI4oy4FMHcCJPHcDS6J2A2EqUQpJhohQDexSef15DBCwAAAABJRU5ErkJggg==) repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-symbol,
|
.hljs-symbol,
|
||||||
@@ -84,7 +84,7 @@ grayscale style (c) MY Sun <simonmysun@gmail.com>
|
|||||||
|
|
||||||
.hljs-deletion {
|
.hljs-deletion {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAYAAABS3WWCAAAAE0lEQVQIW2MMDQ39zzhz5kwIAQAyxweWgUHd1AAAAABJRU5ErkJggg==) repeat;
|
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAYAAABS3WWCAAAAE0lEQVQIW2MMDQ39zzhz5kwIAQAyxweWgUHd1AAAAABJRU5ErkJggg==) repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-addition {
|
.hljs-addition {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid)
|
|||||||
.hljs-literal,
|
.hljs-literal,
|
||||||
.hljs-deletion,
|
.hljs-deletion,
|
||||||
.hljs-link {
|
.hljs-link {
|
||||||
color: #cc6666
|
color: #cc6666;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*color: fg_green*/
|
/*color: fg_green*/
|
||||||
@@ -64,7 +64,7 @@ vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid)
|
|||||||
.hljs-attribute,
|
.hljs-attribute,
|
||||||
.hljs-code,
|
.hljs-code,
|
||||||
.hljs-selector-id {
|
.hljs-selector-id {
|
||||||
color: #b294bb;
|
color: #b294bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*color: fg_blue*/
|
/*color: fg_blue*/
|
||||||
@@ -72,7 +72,7 @@ vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid)
|
|||||||
.hljs-selector-tag,
|
.hljs-selector-tag,
|
||||||
.hljs-bullet,
|
.hljs-bullet,
|
||||||
.hljs-tag {
|
.hljs-tag {
|
||||||
color: #81a2be;
|
color: #81a2be;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*color: fg_aqua*/
|
/*color: fg_aqua*/
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
|
|
||||||
.hljs-number,
|
.hljs-number,
|
||||||
.hljs-deletion {
|
.hljs-deletion {
|
||||||
color:#ff73fd;
|
color: #ff73fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-emphasis {
|
.hljs-emphasis {
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ Monokai style - ported by Luigi Maselli - http://grigio.org
|
|||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
background: #272822; color: #ddd;
|
background: #272822;
|
||||||
|
color: #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-tag,
|
.hljs-tag,
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hljs-selector-class {
|
.hljs-selector-class {
|
||||||
color: #A082BD
|
color: #a082bd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-keyword,
|
.hljs-keyword,
|
||||||
|
|||||||
@@ -21,12 +21,13 @@ NOTE_2: Color names provided in comments were derived using "Name that Color" on
|
|||||||
http://chir.ag/projects/name-that-color
|
http://chir.ag/projects/name-that-color
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.hljs { /* Common set of rules required by highlight.js (don'r remove!) */
|
.hljs {
|
||||||
display: block;
|
/* Common set of rules required by highlight.js (don'r remove!) */
|
||||||
overflow-x: auto;
|
display: block;
|
||||||
padding: 0.5em;
|
overflow-x: auto;
|
||||||
background: #FFFFDF; /* Half and Half (approx.) */
|
padding: 0.5em;
|
||||||
/* --- Uncomment to add PureBASIC native IDE styled font!
|
background: #ffffdf; /* Half and Half (approx.) */
|
||||||
|
/* --- Uncomment to add PureBASIC native IDE styled font!
|
||||||
font-family: Consolas;
|
font-family: Consolas;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
@@ -39,7 +40,7 @@ NOTE_2: Color names provided in comments were derived using "Name that Color" on
|
|||||||
.hljs-attr,
|
.hljs-attr,
|
||||||
.hljs-params,
|
.hljs-params,
|
||||||
.hljs-subst {
|
.hljs-subst {
|
||||||
color: #000000; /* Black */
|
color: #000000; /* Black */
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-comment, /* --- used for PureBASIC Comments --- */
|
.hljs-comment, /* --- used for PureBASIC Comments --- */
|
||||||
@@ -47,14 +48,14 @@ NOTE_2: Color names provided in comments were derived using "Name that Color" on
|
|||||||
.hljs-section,
|
.hljs-section,
|
||||||
.hljs-selector-pseudo,
|
.hljs-selector-pseudo,
|
||||||
.hljs-addition {
|
.hljs-addition {
|
||||||
color: #00AAAA; /* Persian Green (approx.) */
|
color: #00aaaa; /* Persian Green (approx.) */
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-title, /* --- used for PureBASIC Procedures Names --- */
|
.hljs-title, /* --- used for PureBASIC Procedures Names --- */
|
||||||
.hljs-tag,
|
.hljs-tag,
|
||||||
.hljs-variable,
|
.hljs-variable,
|
||||||
.hljs-code {
|
.hljs-code {
|
||||||
color: #006666; /* Blue Stone (approx.) */
|
color: #006666; /* Blue Stone (approx.) */
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-keyword, /* --- used for PureBASIC Keywords --- */
|
.hljs-keyword, /* --- used for PureBASIC Keywords --- */
|
||||||
@@ -63,34 +64,34 @@ NOTE_2: Color names provided in comments were derived using "Name that Color" on
|
|||||||
.hljs-selector-class,
|
.hljs-selector-class,
|
||||||
.hljs-built_in,
|
.hljs-built_in,
|
||||||
.hljs-builtin-name {
|
.hljs-builtin-name {
|
||||||
color: #006666; /* Blue Stone (approx.) */
|
color: #006666; /* Blue Stone (approx.) */
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-string, /* --- used for PureBASIC Strings --- */
|
.hljs-string, /* --- used for PureBASIC Strings --- */
|
||||||
.hljs-selector-attr {
|
.hljs-selector-attr {
|
||||||
color: #0080FF; /* Azure Radiance (approx.) */
|
color: #0080ff; /* Azure Radiance (approx.) */
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-symbol, /* --- used for PureBASIC Constants --- */
|
.hljs-symbol, /* --- used for PureBASIC Constants --- */
|
||||||
.hljs-link,
|
.hljs-link,
|
||||||
.hljs-deletion,
|
.hljs-deletion,
|
||||||
.hljs-attribute {
|
.hljs-attribute {
|
||||||
color: #924B72; /* Cannon Pink (approx.) */
|
color: #924b72; /* Cannon Pink (approx.) */
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-meta,
|
.hljs-meta,
|
||||||
.hljs-literal,
|
.hljs-literal,
|
||||||
.hljs-selector-id {
|
.hljs-selector-id {
|
||||||
color: #924B72; /* Cannon Pink (approx.) */
|
color: #924b72; /* Cannon Pink (approx.) */
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-strong,
|
.hljs-strong,
|
||||||
.hljs-name {
|
.hljs-name {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-emphasis {
|
.hljs-emphasis {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ Qt Creator dark color scheme
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
.hljs {
|
.hljs {
|
||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
@@ -32,8 +31,7 @@ Qt Creator dark color scheme
|
|||||||
color: #ff55ff;
|
color: #ff55ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-code
|
.hljs-code .hljs-selector-class {
|
||||||
.hljs-selector-class {
|
|
||||||
color: #aaaaff;
|
color: #aaaaff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ Qt Creator light color scheme
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
.hljs {
|
.hljs {
|
||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
@@ -32,8 +31,7 @@ Qt Creator light color scheme
|
|||||||
color: #000080;
|
color: #000080;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-code
|
.hljs-code .hljs-selector-class {
|
||||||
.hljs-selector-class {
|
|
||||||
color: #800080;
|
color: #800080;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +57,7 @@ Qt Creator light color scheme
|
|||||||
.hljs-variable,
|
.hljs-variable,
|
||||||
.hljs-params,
|
.hljs-params,
|
||||||
.hljs-class .hljs-title {
|
.hljs-class .hljs-title {
|
||||||
color: #0055AF;
|
color: #0055af;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-string,
|
.hljs-string,
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ Railscasts-like style (c) Visoft, Inc. (Damien White)
|
|||||||
color: #da4939;
|
color: #da4939;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.hljs-symbol,
|
.hljs-symbol,
|
||||||
.hljs-bullet,
|
.hljs-bullet,
|
||||||
.hljs-built_in,
|
.hljs-built_in,
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ Style with support for rainbow parens
|
|||||||
color: #d1d9e1;
|
color: #d1d9e1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.hljs-comment,
|
.hljs-comment,
|
||||||
.hljs-quote {
|
.hljs-quote {
|
||||||
color: #969896;
|
color: #969896;
|
||||||
@@ -50,7 +49,7 @@ Style with support for rainbow parens
|
|||||||
.hljs-template-variable,
|
.hljs-template-variable,
|
||||||
.hljs-selector-id,
|
.hljs-selector-id,
|
||||||
.hljs-class .hljs-title {
|
.hljs-class .hljs-title {
|
||||||
color: #ffcc66;
|
color: #ffcc66;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-section,
|
.hljs-section,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
background: #F0F0F0;
|
background: #f0f0f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Base color: saturation 0; */
|
/* Base color: saturation 0; */
|
||||||
@@ -31,15 +31,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hljs-attribute {
|
.hljs-attribute {
|
||||||
color: #0E9A00;
|
color: #0e9a00;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-function {
|
.hljs-function {
|
||||||
color: #99069A;
|
color: #99069a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-builtin-name {
|
.hljs-builtin-name {
|
||||||
color: #99069A;
|
color: #99069a;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* User color: hue: 0 */
|
/* User color: hue: 0 */
|
||||||
@@ -68,24 +68,22 @@
|
|||||||
.hljs-link,
|
.hljs-link,
|
||||||
.hljs-selector-attr,
|
.hljs-selector-attr,
|
||||||
.hljs-selector-pseudo {
|
.hljs-selector-pseudo {
|
||||||
color: #BC6060;
|
color: #bc6060;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Language color: hue: 90; */
|
/* Language color: hue: 90; */
|
||||||
|
|
||||||
.hljs-literal {
|
.hljs-literal {
|
||||||
color: #78A960;
|
color: #78a960;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-built_in,
|
.hljs-built_in,
|
||||||
.hljs-bullet,
|
.hljs-bullet,
|
||||||
.hljs-code,
|
.hljs-code,
|
||||||
.hljs-addition {
|
.hljs-addition {
|
||||||
color: #0C9A9A;
|
color: #0c9a9a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Meta color: hue: 200 */
|
/* Meta color: hue: 200 */
|
||||||
|
|
||||||
.hljs-meta {
|
.hljs-meta {
|
||||||
@@ -96,7 +94,6 @@
|
|||||||
color: #4d99bf;
|
color: #4d99bf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Misc effects */
|
/* Misc effects */
|
||||||
|
|
||||||
.hljs-emphasis {
|
.hljs-emphasis {
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ School Book style from goldblog.com.ua (c) Zaripov Yura <yur4ik7@ukr.net>
|
|||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding: 15px 0.5em 0.5em 30px;
|
padding: 15px 0.5em 0.5em 30px;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
line-height:16px;
|
line-height: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre{
|
pre {
|
||||||
background:#f6f6ae url(./school-book.png);
|
background: #f6f6ae url(./school-book.png);
|
||||||
border-top: solid 2px #d2e8b9;
|
border-top: solid 2px #d2e8b9;
|
||||||
border-bottom: solid 1px #d2e8b9;
|
border-bottom: solid 1px #d2e8b9;
|
||||||
}
|
}
|
||||||
@@ -21,8 +21,8 @@ pre{
|
|||||||
.hljs-keyword,
|
.hljs-keyword,
|
||||||
.hljs-selector-tag,
|
.hljs-selector-tag,
|
||||||
.hljs-literal {
|
.hljs-literal {
|
||||||
color:#005599;
|
color: #005599;
|
||||||
font-weight:bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs,
|
.hljs,
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ Visual Studio-like style based on original C# coloring by Jason Diamond <jason@d
|
|||||||
color: #00b0e8;
|
color: #00b0e8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.hljs-emphasis {
|
.hljs-emphasis {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,39 +7,39 @@
|
|||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
background: #1E1E1E;
|
background: #1e1e1e;
|
||||||
color: #DCDCDC;
|
color: #dcdcdc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-keyword,
|
.hljs-keyword,
|
||||||
.hljs-literal,
|
.hljs-literal,
|
||||||
.hljs-symbol,
|
.hljs-symbol,
|
||||||
.hljs-name {
|
.hljs-name {
|
||||||
color: #569CD6;
|
color: #569cd6;
|
||||||
}
|
}
|
||||||
.hljs-link {
|
.hljs-link {
|
||||||
color: #569CD6;
|
color: #569cd6;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-built_in,
|
.hljs-built_in,
|
||||||
.hljs-type {
|
.hljs-type {
|
||||||
color: #4EC9B0;
|
color: #4ec9b0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-number,
|
.hljs-number,
|
||||||
.hljs-class {
|
.hljs-class {
|
||||||
color: #B8D7A3;
|
color: #b8d7a3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-string,
|
.hljs-string,
|
||||||
.hljs-meta-string {
|
.hljs-meta-string {
|
||||||
color: #D69D85;
|
color: #d69d85;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-regexp,
|
.hljs-regexp,
|
||||||
.hljs-template-tag {
|
.hljs-template-tag {
|
||||||
color: #9A5334;
|
color: #9a5334;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-subst,
|
.hljs-subst,
|
||||||
@@ -47,34 +47,34 @@
|
|||||||
.hljs-title,
|
.hljs-title,
|
||||||
.hljs-params,
|
.hljs-params,
|
||||||
.hljs-formula {
|
.hljs-formula {
|
||||||
color: #DCDCDC;
|
color: #dcdcdc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-comment,
|
.hljs-comment,
|
||||||
.hljs-quote {
|
.hljs-quote {
|
||||||
color: #57A64A;
|
color: #57a64a;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-doctag {
|
.hljs-doctag {
|
||||||
color: #608B4E;
|
color: #608b4e;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-meta,
|
.hljs-meta,
|
||||||
.hljs-meta-keyword,
|
.hljs-meta-keyword,
|
||||||
.hljs-tag {
|
.hljs-tag {
|
||||||
color: #9B9B9B;
|
color: #9b9b9b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-variable,
|
.hljs-variable,
|
||||||
.hljs-template-variable {
|
.hljs-template-variable {
|
||||||
color: #BD63C5;
|
color: #bd63c5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-attr,
|
.hljs-attr,
|
||||||
.hljs-attribute,
|
.hljs-attribute,
|
||||||
.hljs-builtin-name {
|
.hljs-builtin-name {
|
||||||
color: #9CDCFE;
|
color: #9cdcfe;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-section {
|
.hljs-section {
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
.hljs-selector-class,
|
.hljs-selector-class,
|
||||||
.hljs-selector-attr,
|
.hljs-selector-attr,
|
||||||
.hljs-selector-pseudo {
|
.hljs-selector-pseudo {
|
||||||
color: #D7BA7D;
|
color: #d7ba7d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-addition {
|
.hljs-addition {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
xt256.css
|
xt256.css
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ based on dark.css by Ivan Sagalaev
|
|||||||
color: #7f9f7f;
|
color: #7f9f7f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.hljs-emphasis {
|
.hljs-emphasis {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,18 +18,18 @@ export default defineComponent({
|
|||||||
code: {
|
code: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: ""
|
default: "",
|
||||||
},
|
},
|
||||||
formatHtml: {
|
formatHtml: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
lang: {
|
lang: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: ""
|
default: "",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
setup(props: any, ctx: any) {
|
setup(props: any, ctx: any) {
|
||||||
const highlightHTMLRef: Ref = ref("");
|
const highlightHTMLRef: Ref = ref("");
|
||||||
@@ -42,7 +42,7 @@ export default defineComponent({
|
|||||||
doHighlight();
|
doHighlight();
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: true
|
immediate: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -52,9 +52,9 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
highlightHTMLRef,
|
highlightHTMLRef,
|
||||||
doHighlight
|
doHighlight,
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -3,40 +3,40 @@
|
|||||||
// 功能
|
// 功能
|
||||||
// 将HTML字符串格式化
|
// 将HTML字符串格式化
|
||||||
|
|
||||||
const format = (function() {
|
const format = (function () {
|
||||||
function style_html(html_source, indent_size, indent_character, max_char) {
|
function style_html(html_source, indent_size, indent_character, max_char) {
|
||||||
var Parser, multi_parser;
|
var Parser, multi_parser;
|
||||||
function Parser() {
|
function Parser() {
|
||||||
this.pos = 0;
|
this.pos = 0;
|
||||||
this.token = '';
|
this.token = "";
|
||||||
this.current_mode = 'CONTENT';
|
this.current_mode = "CONTENT";
|
||||||
this.tags = {
|
this.tags = {
|
||||||
parent: 'parent1',
|
parent: "parent1",
|
||||||
parentcount: 1,
|
parentcount: 1,
|
||||||
parent1: ''
|
parent1: "",
|
||||||
};
|
};
|
||||||
this.tag_type = '';
|
this.tag_type = "";
|
||||||
this.token_text = this.last_token = this.last_text = this.token_type = '';
|
this.token_text = this.last_token = this.last_text = this.token_type = "";
|
||||||
this.Utils = {
|
this.Utils = {
|
||||||
whitespace: "\n\r\t ".split(''),
|
whitespace: "\n\r\t ".split(""),
|
||||||
single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed'.split(','),
|
single_token: "br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed".split(","),
|
||||||
extra_liners: 'head,body,/html'.split(','),
|
extra_liners: "head,body,/html".split(","),
|
||||||
in_array: function(what, arr) {
|
in_array: function (what, arr) {
|
||||||
for (var i = 0; i < arr.length; i++) {
|
for (var i = 0; i < arr.length; i++) {
|
||||||
if (what === arr[i]) {
|
if (what === arr[i]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
this.get_content = function() {
|
this.get_content = function () {
|
||||||
var char = '';
|
var char = "";
|
||||||
var content = [];
|
var content = [];
|
||||||
var space = false;
|
var space = false;
|
||||||
while (this.input.charAt(this.pos) !== '<') {
|
while (this.input.charAt(this.pos) !== "<") {
|
||||||
if (this.pos >= this.input.length) {
|
if (this.pos >= this.input.length) {
|
||||||
return content.length ? content.join('') : ['', 'TK_EOF'];
|
return content.length ? content.join("") : ["", "TK_EOF"];
|
||||||
}
|
}
|
||||||
char = this.input.charAt(this.pos);
|
char = this.input.charAt(this.pos);
|
||||||
this.pos++;
|
this.pos++;
|
||||||
@@ -49,78 +49,78 @@ const format = (function() {
|
|||||||
continue;
|
continue;
|
||||||
} else if (space) {
|
} else if (space) {
|
||||||
if (this.line_char_count >= this.max_char) {
|
if (this.line_char_count >= this.max_char) {
|
||||||
content.push('\n');
|
content.push("\n");
|
||||||
for (var i = 0; i < this.indent_level; i++) {
|
for (var i = 0; i < this.indent_level; i++) {
|
||||||
content.push(this.indent_string);
|
content.push(this.indent_string);
|
||||||
}
|
}
|
||||||
this.line_char_count = 0;
|
this.line_char_count = 0;
|
||||||
} else {
|
} else {
|
||||||
content.push(' ');
|
content.push(" ");
|
||||||
this.line_char_count++;
|
this.line_char_count++;
|
||||||
}
|
}
|
||||||
space = false;
|
space = false;
|
||||||
}
|
}
|
||||||
content.push(char);
|
content.push(char);
|
||||||
}
|
}
|
||||||
return content.length ? content.join('') : '';
|
return content.length ? content.join("") : "";
|
||||||
}
|
};
|
||||||
this.get_script = function() {
|
this.get_script = function () {
|
||||||
var char = '';
|
var char = "";
|
||||||
var content = [];
|
var content = [];
|
||||||
var reg_match = new RegExp('\<\/script' + '\>', 'igm');
|
var reg_match = new RegExp("</script" + ">", "igm");
|
||||||
reg_match.lastIndex = this.pos;
|
reg_match.lastIndex = this.pos;
|
||||||
var reg_array = reg_match.exec(this.input);
|
var reg_array = reg_match.exec(this.input);
|
||||||
var end_script = reg_array ? reg_array.index: this.input.length;
|
var end_script = reg_array ? reg_array.index : this.input.length;
|
||||||
while (this.pos < end_script) {
|
while (this.pos < end_script) {
|
||||||
if (this.pos >= this.input.length) {
|
if (this.pos >= this.input.length) {
|
||||||
return content.length ? content.join('') : ['', 'TK_EOF'];
|
return content.length ? content.join("") : ["", "TK_EOF"];
|
||||||
}
|
}
|
||||||
char = this.input.charAt(this.pos);
|
char = this.input.charAt(this.pos);
|
||||||
this.pos++;
|
this.pos++;
|
||||||
content.push(char);
|
content.push(char);
|
||||||
}
|
}
|
||||||
return content.length ? content.join('') : '';
|
return content.length ? content.join("") : "";
|
||||||
}
|
};
|
||||||
this.record_tag = function(tag) {
|
this.record_tag = function (tag) {
|
||||||
if (this.tags[tag + 'count']) {
|
if (this.tags[tag + "count"]) {
|
||||||
this.tags[tag + 'count']++;
|
this.tags[tag + "count"]++;
|
||||||
this.tags[tag + this.tags[tag + 'count']] = this.indent_level;
|
this.tags[tag + this.tags[tag + "count"]] = this.indent_level;
|
||||||
} else {
|
} else {
|
||||||
this.tags[tag + 'count'] = 1;
|
this.tags[tag + "count"] = 1;
|
||||||
this.tags[tag + this.tags[tag + 'count']] = this.indent_level;
|
this.tags[tag + this.tags[tag + "count"]] = this.indent_level;
|
||||||
}
|
}
|
||||||
this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent;
|
this.tags[tag + this.tags[tag + "count"] + "parent"] = this.tags.parent;
|
||||||
this.tags.parent = tag + this.tags[tag + 'count'];
|
this.tags.parent = tag + this.tags[tag + "count"];
|
||||||
}
|
};
|
||||||
this.retrieve_tag = function(tag) {
|
this.retrieve_tag = function (tag) {
|
||||||
if (this.tags[tag + 'count']) {
|
if (this.tags[tag + "count"]) {
|
||||||
var temp_parent = this.tags.parent;
|
var temp_parent = this.tags.parent;
|
||||||
while (temp_parent) {
|
while (temp_parent) {
|
||||||
if (tag + this.tags[tag + 'count'] === temp_parent) {
|
if (tag + this.tags[tag + "count"] === temp_parent) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
temp_parent = this.tags[temp_parent + 'parent'];
|
temp_parent = this.tags[temp_parent + "parent"];
|
||||||
}
|
}
|
||||||
if (temp_parent) {
|
if (temp_parent) {
|
||||||
this.indent_level = this.tags[tag + this.tags[tag + 'count']];
|
this.indent_level = this.tags[tag + this.tags[tag + "count"]];
|
||||||
this.tags.parent = this.tags[temp_parent + 'parent'];
|
this.tags.parent = this.tags[temp_parent + "parent"];
|
||||||
}
|
}
|
||||||
delete this.tags[tag + this.tags[tag + 'count'] + 'parent'];
|
delete this.tags[tag + this.tags[tag + "count"] + "parent"];
|
||||||
delete this.tags[tag + this.tags[tag + 'count']];
|
delete this.tags[tag + this.tags[tag + "count"]];
|
||||||
if (this.tags[tag + 'count'] == 1) {
|
if (this.tags[tag + "count"] == 1) {
|
||||||
delete this.tags[tag + 'count'];
|
delete this.tags[tag + "count"];
|
||||||
} else {
|
} else {
|
||||||
this.tags[tag + 'count']--;
|
this.tags[tag + "count"]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
this.get_tag = function() {
|
this.get_tag = function () {
|
||||||
var char = '';
|
var char = "";
|
||||||
var content = [];
|
var content = [];
|
||||||
var space = false;
|
var space = false;
|
||||||
do {
|
do {
|
||||||
if (this.pos >= this.input.length) {
|
if (this.pos >= this.input.length) {
|
||||||
return content.length ? content.join('') : ['', 'TK_EOF'];
|
return content.length ? content.join("") : ["", "TK_EOF"];
|
||||||
}
|
}
|
||||||
char = this.input.charAt(this.pos);
|
char = this.input.charAt(this.pos);
|
||||||
this.pos++;
|
this.pos++;
|
||||||
@@ -131,92 +131,92 @@ const format = (function() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (char === "'" || char === '"') {
|
if (char === "'" || char === '"') {
|
||||||
if (!content[1] || content[1] !== '!') {
|
if (!content[1] || content[1] !== "!") {
|
||||||
char += this.get_unformatted(char);
|
char += this.get_unformatted(char);
|
||||||
space = true;
|
space = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (char === '=') {
|
if (char === "=") {
|
||||||
space = false;
|
space = false;
|
||||||
}
|
}
|
||||||
if (content.length && content[content.length - 1] !== '=' && char !== '>' && space) {
|
if (content.length && content[content.length - 1] !== "=" && char !== ">" && space) {
|
||||||
if (this.line_char_count >= this.max_char) {
|
if (this.line_char_count >= this.max_char) {
|
||||||
this.print_newline(false, content);
|
this.print_newline(false, content);
|
||||||
this.line_char_count = 0;
|
this.line_char_count = 0;
|
||||||
} else {
|
} else {
|
||||||
content.push(' ');
|
content.push(" ");
|
||||||
this.line_char_count++;
|
this.line_char_count++;
|
||||||
}
|
}
|
||||||
space = false;
|
space = false;
|
||||||
}
|
}
|
||||||
content.push(char);
|
content.push(char);
|
||||||
} while ( char !== '>');
|
} while (char !== ">");
|
||||||
var tag_complete = content.join('');
|
var tag_complete = content.join("");
|
||||||
var tag_index;
|
var tag_index;
|
||||||
if (tag_complete.indexOf(' ') != -1) {
|
if (tag_complete.indexOf(" ") != -1) {
|
||||||
tag_index = tag_complete.indexOf(' ');
|
tag_index = tag_complete.indexOf(" ");
|
||||||
} else {
|
} else {
|
||||||
tag_index = tag_complete.indexOf('>');
|
tag_index = tag_complete.indexOf(">");
|
||||||
}
|
}
|
||||||
var tag_check = tag_complete.substring(1, tag_index).toLowerCase();
|
var tag_check = tag_complete.substring(1, tag_index).toLowerCase();
|
||||||
if (tag_complete.charAt(tag_complete.length - 2) === '/' || this.Utils.in_array(tag_check, this.Utils.single_token)) {
|
if (tag_complete.charAt(tag_complete.length - 2) === "/" || this.Utils.in_array(tag_check, this.Utils.single_token)) {
|
||||||
this.tag_type = 'SINGLE';
|
this.tag_type = "SINGLE";
|
||||||
} else if (tag_check === 'script') {
|
} else if (tag_check === "script") {
|
||||||
this.record_tag(tag_check);
|
this.record_tag(tag_check);
|
||||||
this.tag_type = 'SCRIPT';
|
this.tag_type = "SCRIPT";
|
||||||
} else if (tag_check === 'style') {
|
} else if (tag_check === "style") {
|
||||||
this.record_tag(tag_check);
|
this.record_tag(tag_check);
|
||||||
this.tag_type = 'STYLE';
|
this.tag_type = "STYLE";
|
||||||
} else if (tag_check.charAt(0) === '!') {
|
} else if (tag_check.charAt(0) === "!") {
|
||||||
if (tag_check.indexOf('[if') != -1) {
|
if (tag_check.indexOf("[if") != -1) {
|
||||||
if (tag_complete.indexOf('!IE') != -1) {
|
if (tag_complete.indexOf("!IE") != -1) {
|
||||||
var comment = this.get_unformatted('-->', tag_complete);
|
var comment = this.get_unformatted("-->", tag_complete);
|
||||||
content.push(comment);
|
content.push(comment);
|
||||||
}
|
}
|
||||||
this.tag_type = 'START';
|
this.tag_type = "START";
|
||||||
} else if (tag_check.indexOf('[endif') != -1) {
|
} else if (tag_check.indexOf("[endif") != -1) {
|
||||||
this.tag_type = 'END';
|
this.tag_type = "END";
|
||||||
this.unindent();
|
this.unindent();
|
||||||
} else if (tag_check.indexOf('[cdata[') != -1) {
|
} else if (tag_check.indexOf("[cdata[") != -1) {
|
||||||
var comment = this.get_unformatted(']]>', tag_complete);
|
var comment = this.get_unformatted("]]>", tag_complete);
|
||||||
content.push(comment);
|
content.push(comment);
|
||||||
this.tag_type = 'SINGLE';
|
this.tag_type = "SINGLE";
|
||||||
} else {
|
} else {
|
||||||
var comment = this.get_unformatted('-->', tag_complete);
|
var comment = this.get_unformatted("-->", tag_complete);
|
||||||
content.push(comment);
|
content.push(comment);
|
||||||
this.tag_type = 'SINGLE';
|
this.tag_type = "SINGLE";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (tag_check.charAt(0) === '/') {
|
if (tag_check.charAt(0) === "/") {
|
||||||
this.retrieve_tag(tag_check.substring(1));
|
this.retrieve_tag(tag_check.substring(1));
|
||||||
this.tag_type = 'END';
|
this.tag_type = "END";
|
||||||
} else {
|
} else {
|
||||||
this.record_tag(tag_check);
|
this.record_tag(tag_check);
|
||||||
this.tag_type = 'START';
|
this.tag_type = "START";
|
||||||
}
|
}
|
||||||
if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) {
|
if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) {
|
||||||
this.print_newline(true, this.output);
|
this.print_newline(true, this.output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return content.join('');
|
return content.join("");
|
||||||
}
|
};
|
||||||
this.get_unformatted = function(delimiter, orig_tag) {
|
this.get_unformatted = function (delimiter, orig_tag) {
|
||||||
if (orig_tag && orig_tag.indexOf(delimiter) != -1) {
|
if (orig_tag && orig_tag.indexOf(delimiter) != -1) {
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
var char = '';
|
var char = "";
|
||||||
var content = '';
|
var content = "";
|
||||||
var space = true;
|
var space = true;
|
||||||
do {
|
do {
|
||||||
char = this.input.charAt(this.pos);
|
char = this.input.charAt(this.pos);
|
||||||
this.pos++
|
this.pos++;
|
||||||
if (this.Utils.in_array(char, this.Utils.whitespace)) {
|
if (this.Utils.in_array(char, this.Utils.whitespace)) {
|
||||||
if (!space) {
|
if (!space) {
|
||||||
this.line_char_count--;
|
this.line_char_count--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (char === '\n' || char === '\r') {
|
if (char === "\n" || char === "\r") {
|
||||||
content += '\n';
|
content += "\n";
|
||||||
for (var i = 0; i < this.indent_level; i++) {
|
for (var i = 0; i < this.indent_level; i++) {
|
||||||
content += this.indent_string;
|
content += this.indent_string;
|
||||||
}
|
}
|
||||||
@@ -228,44 +228,43 @@ const format = (function() {
|
|||||||
content += char;
|
content += char;
|
||||||
this.line_char_count++;
|
this.line_char_count++;
|
||||||
space = true;
|
space = true;
|
||||||
|
} while (content.indexOf(delimiter) == -1);
|
||||||
} while ( content . indexOf ( delimiter ) == -1);
|
|
||||||
return content;
|
return content;
|
||||||
}
|
};
|
||||||
this.get_token = function() {
|
this.get_token = function () {
|
||||||
var token;
|
var token;
|
||||||
if (this.last_token === 'TK_TAG_SCRIPT') {
|
if (this.last_token === "TK_TAG_SCRIPT") {
|
||||||
var temp_token = this.get_script();
|
var temp_token = this.get_script();
|
||||||
if (typeof temp_token !== 'string') {
|
if (typeof temp_token !== "string") {
|
||||||
return temp_token;
|
return temp_token;
|
||||||
}
|
}
|
||||||
//token = js_beautify(temp_token, this.indent_size, this.indent_character, this.indent_level);
|
//token = js_beautify(temp_token, this.indent_size, this.indent_character, this.indent_level);
|
||||||
//return [token, 'TK_CONTENT'];
|
//return [token, 'TK_CONTENT'];
|
||||||
return [temp_token, 'TK_CONTENT'];
|
return [temp_token, "TK_CONTENT"];
|
||||||
}
|
}
|
||||||
if (this.current_mode === 'CONTENT') {
|
if (this.current_mode === "CONTENT") {
|
||||||
token = this.get_content();
|
token = this.get_content();
|
||||||
if (typeof token !== 'string') {
|
if (typeof token !== "string") {
|
||||||
return token;
|
return token;
|
||||||
} else {
|
} else {
|
||||||
return [token, 'TK_CONTENT'];
|
return [token, "TK_CONTENT"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.current_mode === 'TAG') {
|
if (this.current_mode === "TAG") {
|
||||||
token = this.get_tag();
|
token = this.get_tag();
|
||||||
if (typeof token !== 'string') {
|
if (typeof token !== "string") {
|
||||||
return token;
|
return token;
|
||||||
} else {
|
} else {
|
||||||
var tag_name_type = 'TK_TAG_' + this.tag_type;
|
var tag_name_type = "TK_TAG_" + this.tag_type;
|
||||||
return [token, tag_name_type];
|
return [token, tag_name_type];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
this.printer = function(js_source, indent_character, indent_size, max_char) {
|
this.printer = function (js_source, indent_character, indent_size, max_char) {
|
||||||
this.input = js_source || '';
|
this.input = js_source || "";
|
||||||
this.output = [];
|
this.output = [];
|
||||||
this.indent_character = indent_character || ' ';
|
this.indent_character = indent_character || " ";
|
||||||
this.indent_string = '';
|
this.indent_string = "";
|
||||||
this.indent_size = indent_size || 2;
|
this.indent_size = indent_size || 2;
|
||||||
this.indent_level = 0;
|
this.indent_level = 0;
|
||||||
this.max_char = max_char || 70;
|
this.max_char = max_char || 70;
|
||||||
@@ -273,7 +272,7 @@ const format = (function() {
|
|||||||
for (var i = 0; i < this.indent_size; i++) {
|
for (var i = 0; i < this.indent_size; i++) {
|
||||||
this.indent_string += this.indent_character;
|
this.indent_string += this.indent_character;
|
||||||
}
|
}
|
||||||
this.print_newline = function(ignore, arr) {
|
this.print_newline = function (ignore, arr) {
|
||||||
this.line_char_count = 0;
|
this.line_char_count = 0;
|
||||||
if (!arr || !arr.length) {
|
if (!arr || !arr.length) {
|
||||||
return;
|
return;
|
||||||
@@ -283,23 +282,23 @@ const format = (function() {
|
|||||||
arr.pop();
|
arr.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
arr.push('\n');
|
arr.push("\n");
|
||||||
for (var i = 0; i < this.indent_level; i++) {
|
for (var i = 0; i < this.indent_level; i++) {
|
||||||
arr.push(this.indent_string);
|
arr.push(this.indent_string);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
this.print_token = function(text) {
|
this.print_token = function (text) {
|
||||||
this.output.push(text);
|
this.output.push(text);
|
||||||
}
|
};
|
||||||
this.indent = function() {
|
this.indent = function () {
|
||||||
this.indent_level++;
|
this.indent_level++;
|
||||||
}
|
};
|
||||||
this.unindent = function() {
|
this.unindent = function () {
|
||||||
if (this.indent_level > 0) {
|
if (this.indent_level > 0) {
|
||||||
this.indent_level--;
|
this.indent_level--;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
multi_parser = new Parser();
|
multi_parser = new Parser();
|
||||||
@@ -308,58 +307,56 @@ const format = (function() {
|
|||||||
var t = multi_parser.get_token();
|
var t = multi_parser.get_token();
|
||||||
multi_parser.token_text = t[0];
|
multi_parser.token_text = t[0];
|
||||||
multi_parser.token_type = t[1];
|
multi_parser.token_type = t[1];
|
||||||
if (multi_parser.token_type === 'TK_EOF') {
|
if (multi_parser.token_type === "TK_EOF") {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (multi_parser.token_type) {
|
switch (multi_parser.token_type) {
|
||||||
case 'TK_TAG_START':
|
case "TK_TAG_START":
|
||||||
case 'TK_TAG_SCRIPT':
|
case "TK_TAG_SCRIPT":
|
||||||
case 'TK_TAG_STYLE':
|
case "TK_TAG_STYLE":
|
||||||
multi_parser.print_newline(false, multi_parser.output);
|
|
||||||
multi_parser.print_token(multi_parser.token_text);
|
|
||||||
multi_parser.indent();
|
|
||||||
multi_parser.current_mode = 'CONTENT';
|
|
||||||
break;
|
|
||||||
case 'TK_TAG_END':
|
|
||||||
multi_parser.print_newline(true, multi_parser.output);
|
|
||||||
multi_parser.print_token(multi_parser.token_text);
|
|
||||||
multi_parser.current_mode = 'CONTENT';
|
|
||||||
break;
|
|
||||||
case 'TK_TAG_SINGLE':
|
|
||||||
multi_parser.print_newline(false, multi_parser.output);
|
|
||||||
multi_parser.print_token(multi_parser.token_text);
|
|
||||||
multi_parser.current_mode = 'CONTENT';
|
|
||||||
break;
|
|
||||||
case 'TK_CONTENT':
|
|
||||||
if (multi_parser.token_text !== '') {
|
|
||||||
multi_parser.print_newline(false, multi_parser.output);
|
multi_parser.print_newline(false, multi_parser.output);
|
||||||
multi_parser.print_token(multi_parser.token_text);
|
multi_parser.print_token(multi_parser.token_text);
|
||||||
}
|
multi_parser.indent();
|
||||||
multi_parser.current_mode = 'TAG';
|
multi_parser.current_mode = "CONTENT";
|
||||||
break;
|
break;
|
||||||
|
case "TK_TAG_END":
|
||||||
|
multi_parser.print_newline(true, multi_parser.output);
|
||||||
|
multi_parser.print_token(multi_parser.token_text);
|
||||||
|
multi_parser.current_mode = "CONTENT";
|
||||||
|
break;
|
||||||
|
case "TK_TAG_SINGLE":
|
||||||
|
multi_parser.print_newline(false, multi_parser.output);
|
||||||
|
multi_parser.print_token(multi_parser.token_text);
|
||||||
|
multi_parser.current_mode = "CONTENT";
|
||||||
|
break;
|
||||||
|
case "TK_CONTENT":
|
||||||
|
if (multi_parser.token_text !== "") {
|
||||||
|
multi_parser.print_newline(false, multi_parser.output);
|
||||||
|
multi_parser.print_token(multi_parser.token_text);
|
||||||
|
}
|
||||||
|
multi_parser.current_mode = "TAG";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
multi_parser.last_token = multi_parser.token_type;
|
multi_parser.last_token = multi_parser.token_type;
|
||||||
multi_parser.last_text = multi_parser.token_text;
|
multi_parser.last_text = multi_parser.token_text;
|
||||||
}
|
}
|
||||||
return multi_parser.output.join('');
|
return multi_parser.output.join("");
|
||||||
}
|
}
|
||||||
return function(data) {
|
return function (data) {
|
||||||
var dataHolder = ['__dataHolder_', [Math.random(), Math.random(), Math.random(), Math.random()].join('_').replace(/[^0-9]/g, '_'), '_'].join('_');
|
var dataHolder = ["__dataHolder_", [Math.random(), Math.random(), Math.random(), Math.random()].join("_").replace(/[^0-9]/g, "_"), "_"].join("_");
|
||||||
var dataHolders = {};
|
var dataHolders = {};
|
||||||
var index = 0;
|
var index = 0;
|
||||||
data = data.replace(/(\")(data:[^\"]*)(\")/g,
|
data = data.replace(/(\")(data:[^\"]*)(\")/g, function ($0, $1, $2, $3) {
|
||||||
function($0, $1, $2, $3) {
|
|
||||||
var name = dataHolder + index++;
|
var name = dataHolder + index++;
|
||||||
dataHolders[name] = $2;
|
dataHolders[name] = $2;
|
||||||
return $1 + name + $3;
|
return $1 + name + $3;
|
||||||
})
|
});
|
||||||
data = style_html(data, 2, ' ', 0x10000000);
|
data = style_html(data, 2, " ", 0x10000000);
|
||||||
data = data.replace(new RegExp(dataHolder + '[0-9]+', 'g'),
|
data = data.replace(new RegExp(dataHolder + "[0-9]+", "g"), function ($0) {
|
||||||
function($0) {
|
|
||||||
return dataHolders[$0];
|
return dataHolders[$0];
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
export default format
|
export default format;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user