diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..d19e4746
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,5 @@
+# These are supported funding model platforms
+
+github: greper
+buy_me_a_coffee: greper
+custom: ['https://afdian.com/a/greper']
diff --git a/README.md b/README.md
index 4ebbc0d0..f0960aaf 100644
--- a/README.md
+++ b/README.md
@@ -152,7 +152,7 @@ https://certd.handfree.work/
## 八、捐赠
************************
-支持开源,为爱发电,我已入驻爱发电
+支持开源,为爱发电,我已入驻爱发电
https://afdian.com/a/greper
发电权益:
@@ -171,6 +171,7 @@ https://afdian.com/a/greper
| 自动部署插件 | 阿里云CDN、腾讯云、七牛CDN、主机部署、宝塔、1Panel等大部分插件 | 群晖 |
| 通知 | 邮件通知、自定义webhook | 邮件免配置、企微、钉钉、飞书、anpush、server酱等 |
+************************
************************
diff --git a/README_en.md b/README_en.md
index 66f67a04..d665a982 100644
--- a/README_en.md
+++ b/README_en.md
@@ -134,6 +134,8 @@ You can also add the author as a friend.
| QR Code |
|
## 8. Donation
+************************
+ [](https://github.com/sponsors/greper)
************************
Support open-source projects and contribute with love. I've joined Afdian.
https://afdian.com/a/greper
diff --git a/packages/plugins/plugin-cert/src/plugin/cert-plugin/base-convert.ts b/packages/plugins/plugin-cert/src/plugin/cert-plugin/base-convert.ts
index e9d59313..e8ad9d75 100644
--- a/packages/plugins/plugin-cert/src/plugin/cert-plugin/base-convert.ts
+++ b/packages/plugins/plugin-cert/src/plugin/cert-plugin/base-convert.ts
@@ -99,6 +99,7 @@ export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
const cert: CertInfo = certReader.toCertInfo();
this.cert = cert;
+ this._result.pipelineVars.certEffectiveTime = dayjs(certReader.detail.notBefore).valueOf();
this._result.pipelineVars.certExpiresTime = dayjs(certReader.detail.notAfter).valueOf();
if (!this._result.pipelinePrivateVars) {
this._result.pipelinePrivateVars = {};
diff --git a/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts b/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts
index b2151871..8fbaa32d 100644
--- a/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts
+++ b/packages/plugins/plugin-cert/src/plugin/cert-plugin/cert-reader.ts
@@ -35,6 +35,7 @@ export class CertReader {
detail: CertificateInfo;
//毫秒时间戳
+ effective: number;
expires: number;
constructor(certInfo: CertInfo) {
this.cert = certInfo;
@@ -52,8 +53,9 @@ export class CertReader {
}
try {
- const { detail, expires } = this.getCrtDetail(this.cert.crt);
+ const { detail, effective, expires } = this.getCrtDetail(this.cert.crt);
this.detail = detail;
+ this.effective = effective.getTime();
this.expires = expires.getTime();
} catch (e) {
throw new Error("证书解析失败:" + e.message);
@@ -102,8 +104,9 @@ export class CertReader {
static readCertDetail(crt: string) {
const detail = crypto.readCertificateInfo(crt.toString());
+ const effective = detail.notBefore;
const expires = detail.notAfter;
- return { detail, expires };
+ return { detail, effective, expires };
}
getAllDomains() {
diff --git a/packages/ui/certd-client/src/locales/langs/en-US/certd.ts b/packages/ui/certd-client/src/locales/langs/en-US/certd.ts
index e26e524e..2dbc451a 100644
--- a/packages/ui/certd-client/src/locales/langs/en-US/certd.ts
+++ b/packages/ui/certd-client/src/locales/langs/en-US/certd.ts
@@ -119,6 +119,7 @@ export default {
scheduledTaskCount: "Scheduled Task Count",
deployTaskCount: "Deployment Task Count",
remainingValidity: "Remaining Validity",
+ effectiveTime: "Effective time",
expiryTime: "Expiry Time",
status: "Status",
lastRun: "Last Run",
@@ -250,7 +251,9 @@ export default {
ok: "Valid",
expired: "Expired",
},
+ certEffectiveTime: "Certificate Effective",
certExpiresTime: "Certificate Expiration",
+ remainingValidity: "Remaining Validity",
expired: "expired",
days: "days",
lastCheckTime: "Last Check Time",
@@ -465,6 +468,7 @@ export default {
validDays: "Valid Days",
expires: " expires",
days: " days",
+ effectiveTime: "Effective Time",
expireTime: "Expiration Time",
certIssuer: "Certificate Issuer",
applyTime: "Application Time",
diff --git a/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts b/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts
index 75005bd9..49fb9d13 100644
--- a/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts
+++ b/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts
@@ -125,6 +125,7 @@ export default {
scheduledTaskCount: "定时任务数",
deployTaskCount: "部署任务数",
remainingValidity: "到期剩余",
+ effectiveTime: "生效时间",
expiryTime: "过期时间",
status: "状态",
lastRun: "最后运行",
@@ -255,7 +256,9 @@ export default {
ok: "正常",
expired: "过期",
},
+ certEffectiveTime: "证书生效时间",
certExpiresTime: "证书到期时间",
+ remainingValidity: "到期剩余",
expired: "过期",
days: "天",
lastCheckTime: "上次检查时间",
@@ -471,6 +474,7 @@ export default {
validDays: "有效天数",
expires: "过期",
days: "天",
+ effectiveTime: "生效时间",
expireTime: "过期时间",
certIssuer: "证书颁发机构",
applyTime: "申请时间",
diff --git a/packages/ui/certd-client/src/views/certd/monitor/cert/crud.tsx b/packages/ui/certd-client/src/views/certd/monitor/cert/crud.tsx
index 97e9754d..23fae996 100644
--- a/packages/ui/certd-client/src/views/certd/monitor/cert/crud.tsx
+++ b/packages/ui/certd-client/src/views/certd/monitor/cert/crud.tsx
@@ -220,22 +220,47 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
sorter: true,
conditionalRender: false,
cellRender({ row }) {
- const value = row.expiresTime;
- if (!value) {
+ const {
+ applyTime,
+ effectiveTime,
+ expiresTime,
+ } = row || {};
+ if (!expiresTime) {
return "-";
}
- const expireDate = dayjs(value).format("YYYY-MM-DD");
- const leftDays = dayjs(value).diff(dayjs(), "day");
+ // 申请时间 ps:此处为证书在certd创建的时间而非实际证书申请时间
+ const applyDate = dayjs(effectiveTime ?? applyTime ?? Date.now()).format("YYYY-MM-DD");
+ // 失效时间
+ const expireDate = dayjs(expiresTime).format("YYYY-MM-DD");
+ // 有效天数 ps:此处证书最小设置为90d
+ const effectiveDays = Math.max(90, dayjs(expiresTime).diff(applyDate, "day"));
+ // 距离失效时间剩余天数
+ const leftDays = dayjs(expiresTime).diff(dayjs(), "day");
const color = leftDays < 20 ? "red" : "#389e0d";
- const percent = (leftDays / 90) * 100;
+ const percent = (leftDays / effectiveDays) * 100;
const textColor = leftDays < 20 ? "red" : leftDays > 60 ? "#389e0d" : "";
const format = () => {
return {`${leftDays}${t("certd.days")}`};
};
+ // console.log('cellRender', 'effectiveDays', effectiveDays, 'expiresTime', expiresTime, 'applyTime', applyTime, 'percent', percent, row)
return ;
},
},
},
+ effectiveTime: {
+ title: t("certd.effectiveTime"),
+ search: {
+ show: false,
+ },
+ type: "datetime",
+ form: {
+ show: false,
+ },
+ column: {
+ sorter: true,
+ show: false,
+ },
+ },
expiresTime: {
title: t("certd.expireTime"),
search: {
diff --git a/packages/ui/certd-client/src/views/certd/monitor/site/crud.tsx b/packages/ui/certd-client/src/views/certd/monitor/site/crud.tsx
index c53a3214..e1189083 100644
--- a/packages/ui/certd-client/src/views/certd/monitor/site/crud.tsx
+++ b/packages/ui/certd-client/src/views/certd/monitor/site/crud.tsx
@@ -345,25 +345,64 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
align: "center",
},
},
+ certEffectiveTime: {
+ title: t("certd.monitor.certEffectiveTime"),
+ search: {
+ show: false,
+ },
+ type: "datetime",
+ form: {
+ show: false,
+ },
+ column: {
+ sorter: true,
+ width: 155,
+ },
+ },
certExpiresTime: {
title: t("certd.monitor.certExpiresTime"),
search: {
show: false,
},
+ type: "datetime",
+ form: {
+ show: false,
+ },
+ column: {
+ sorter: true,
+ width: 155,
+ },
+ },
+ remainingValidity: {
+ title: t("certd.monitor.remainingValidity"),
+ search: {
+ show: false,
+ },
type: "date",
form: {
show: false,
},
column: {
- sorter: true,
- cellRender({ value }) {
- if (!value) {
+ conditionalRender: false,
+ cellRender({ row }) {
+ const {
+ certEffectiveTime: effectiveTime,
+ certExpiresTime: expiresTime,
+ } = row || {};
+ if (!expiresTime) {
return "-";
}
- const expireDate = dayjs(value).format("YYYY-MM-DD");
- const leftDays = dayjs(value).diff(dayjs(), "day");
+ // 申请时间 ps:此处为证书在certd创建的时间而非实际证书申请时间
+ const applyDate = dayjs(effectiveTime ?? Date.now()).format("YYYY-MM-DD");
+ // 失效时间
+ const expireDate = dayjs(expiresTime).format("YYYY-MM-DD");
+ // 有效天数 ps:此处证书最小设置为90d
+ const effectiveDays = Math.max(90, dayjs(expiresTime).diff(applyDate, "day"));
+ // 距离失效时间剩余天数
+ const leftDays = dayjs(expiresTime).diff(dayjs(), "day");
const color = leftDays < 20 ? "red" : "#389e0d";
- const percent = (leftDays / 90) * 100;
+ const percent = (leftDays / effectiveDays) * 100;
+ // console.log('cellRender', 'effectiveDays', effectiveDays, 'expiresTime', expiresTime, 'applyTime', applyTime, 'percent', percent, row)
return `${leftDays}${t("certd.monitor.days")}`} />;
},
},
diff --git a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx
index 9e11102d..8ce42f4c 100644
--- a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx
+++ b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx
@@ -366,23 +366,49 @@ export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys
},
column: {
cellRender({ row }) {
- const value = row.lastVars?.certExpiresTime;
- if (!value) {
+ const {
+ certEffectiveTime: effectiveTime,
+ certExpiresTime: expiresTime,
+ } = row?.lastVars || {};
+ if (!expiresTime) {
return "-";
}
- const expireDate = dayjs(value).format("YYYY-MM-DD");
- const leftDays = dayjs(value).diff(dayjs(), "day");
+ // 申请时间 ps:此处为证书在certd创建的时间而非实际证书申请时间
+ const applyDate = dayjs(effectiveTime ?? Date.now()).format("YYYY-MM-DD");
+ // 失效时间
+ const expireDate = dayjs(expiresTime).format("YYYY-MM-DD");
+ // 有效天数 ps:此处证书最小设置为90d
+ const effectiveDays = Math.max(90, dayjs(expiresTime).diff(applyDate, "day"));
+ // 距离失效时间剩余天数
+ const leftDays = dayjs(expiresTime).diff(dayjs(), "day");
const color = leftDays < 20 ? "red" : "#389e0d";
- const percent = (leftDays / 90) * 100;
+ const percent = (leftDays / effectiveDays) * 100;
const textColor = leftDays < 20 ? "red" : leftDays > 60 ? "#389e0d" : "";
const format = () => {
return {`${leftDays}${t("certd.days")}`};
};
+ // console.log('cellRender', 'effectiveDays', effectiveDays, 'expiresTime', expiresTime, 'applyTime', applyTime, 'percent', percent, row)
return ;
},
width: 150,
},
},
+ "lastVars.certEffectiveTime": {
+ title: t("certd.fields.effectiveTime"),
+ search: {
+ show: false,
+ },
+ type: "datetime",
+ form: {
+ show: false,
+ },
+ column: {
+ sorter: false,
+ show: false,
+ width: 150,
+ align: "center",
+ },
+ },
"lastVars.certExpiresTime": {
title: t("certd.fields.expiryTime"),
search: {
diff --git a/packages/ui/certd-server/db/migration-mysql/v10029__cert_effective_time.sql b/packages/ui/certd-server/db/migration-mysql/v10029__cert_effective_time.sql
new file mode 100644
index 00000000..b38feb3c
--- /dev/null
+++ b/packages/ui/certd-server/db/migration-mysql/v10029__cert_effective_time.sql
@@ -0,0 +1,2 @@
+ALTER TABLE cd_cert_info ADD COLUMN effective_time INTEGER;
+ALTER TABLE cd_site_info ADD COLUMN cert_effective_time INTEGER;
diff --git a/packages/ui/certd-server/db/migration-pg/v10029__cert_effective_time.sql b/packages/ui/certd-server/db/migration-pg/v10029__cert_effective_time.sql
new file mode 100644
index 00000000..b38feb3c
--- /dev/null
+++ b/packages/ui/certd-server/db/migration-pg/v10029__cert_effective_time.sql
@@ -0,0 +1,2 @@
+ALTER TABLE cd_cert_info ADD COLUMN effective_time INTEGER;
+ALTER TABLE cd_site_info ADD COLUMN cert_effective_time INTEGER;
diff --git a/packages/ui/certd-server/db/migration/v10029__cert_effective_time.sql b/packages/ui/certd-server/db/migration/v10029__cert_effective_time.sql
new file mode 100644
index 00000000..b38feb3c
--- /dev/null
+++ b/packages/ui/certd-server/db/migration/v10029__cert_effective_time.sql
@@ -0,0 +1,2 @@
+ALTER TABLE cd_cert_info ADD COLUMN effective_time INTEGER;
+ALTER TABLE cd_site_info ADD COLUMN cert_effective_time INTEGER;
diff --git a/packages/ui/certd-server/src/modules/monitor/entity/cert-info.ts b/packages/ui/certd-server/src/modules/monitor/entity/cert-info.ts
index f16ca87d..807489c9 100644
--- a/packages/ui/certd-server/src/modules/monitor/entity/cert-info.ts
+++ b/packages/ui/certd-server/src/modules/monitor/entity/cert-info.ts
@@ -30,6 +30,9 @@ export class CertInfoEntity {
@Column({ name: 'cert_provider', comment: '证书颁发机构' })
certProvider: string;
+ @Column({ name: 'effective_time', comment: '生效时间' })
+ effectiveTime: number;
+
@Column({ name: 'expires_time', comment: '过期时间' })
expiresTime: number;
diff --git a/packages/ui/certd-server/src/modules/monitor/entity/site-info.ts b/packages/ui/certd-server/src/modules/monitor/entity/site-info.ts
index 1c1e4eda..f4dc9501 100644
--- a/packages/ui/certd-server/src/modules/monitor/entity/site-info.ts
+++ b/packages/ui/certd-server/src/modules/monitor/entity/site-info.ts
@@ -26,6 +26,8 @@ export class SiteInfoEntity {
@Column({ name: 'cert_provider', comment: '证书颁发机构', length: 100 })
certProvider: string;
+ @Column({ name: 'cert_effective_time', comment: '证书生效时间' })
+ certEffectiveTime: number;
@Column({ name: 'cert_expires_time', comment: '证书到期时间' })
certExpiresTime: number;
@Column({ name: 'last_check_time', comment: '上次检查时间' })
diff --git a/packages/ui/certd-server/src/modules/monitor/service/cert-info-service.ts b/packages/ui/certd-server/src/modules/monitor/service/cert-info-service.ts
index 8bb2e8ac..4819bda9 100644
--- a/packages/ui/certd-server/src/modules/monitor/service/cert-info-service.ts
+++ b/packages/ui/certd-server/src/modules/monitor/service/cert-info-service.ts
@@ -164,6 +164,7 @@ export class CertInfoService extends BaseService {
bean.domains = domains.join(',');
bean.domain = domains[0];
bean.domainCount = domains.length;
+ bean.effectiveTime = certReader.effective;
bean.expiresTime = certReader.expires;
bean.certProvider = certReader.detail.issuer.commonName;
bean.userId = userId
diff --git a/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts b/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts
index 4f9f7f9f..8c21d9d4 100644
--- a/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts
+++ b/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts
@@ -134,6 +134,7 @@ export class SiteInfoService extends BaseService {
if (!certi) {
throw new Error("没有发现证书");
}
+ const effective = certi.valid_from;
const expires = certi.valid_to;
const allDomains = certi.subjectaltname?.replaceAll("DNS:", "").split(",") || [];
const mainDomain = certi.subject?.CN;
@@ -149,12 +150,13 @@ export class SiteInfoService extends BaseService {
certDomains: domains.join(","),
certStatus: status,
certProvider: issuer,
+ certEffectiveTime: dayjs(effective).valueOf(),
certExpiresTime: dayjs(expires).valueOf(),
lastCheckTime: dayjs().valueOf(),
error: null,
checkStatus: "ok"
};
- logger.info(`测试站点成功:id=${updateData.id},site=${site.name},expiresTime=${updateData.certExpiresTime}`)
+ logger.info(`测试站点成功:id=${updateData.id},site=${site.name},certEffectiveTime=${updateData.certEffectiveTime},expiresTime=${updateData.certExpiresTime}`)
if (site.ipCheck) {
delete updateData.checkStatus
}