Compare commits

..

1 Commits

Author SHA1 Message Date
greper 8a5eff6581 Revert "perf: 添加AWS Rate Limit应对措施 (#748)"
This reverts commit 56b8c689ec.
2026-06-08 10:29:24 +08:00
26 changed files with 30 additions and 90 deletions
+1 -4
View File
@@ -179,10 +179,7 @@ https://certd.handfree.work/
2. 您的需求我们将优先实现,并且可能将作为专业版功能提供
3. 获得专业版功能
> [50元专业版优惠券限时领取](https://app.handfree.work/subject/#/app/certd/product) https://app.handfree.work/subject/#/app/certd/product
> handfree.work是Certd官方激活码购买平台
[50元专业版优惠券限时领取](https://app.handfree.work/subject/#/app/certd/product)
专业版、商业版特权对比
View File
+1 -1
View File
@@ -263,4 +263,4 @@ export function createChallengeFn(opts = {}) {
// createChallengeFn({logger:{info:console.log}}).walkDnsChallengeRecord("handfree.work")
// createChallengeFn({logger:{info:console.log}}).walkDnsChallengeRecord("handsfree.work")
+2 -2
View File
@@ -4,8 +4,8 @@ VITE_APP_PM_ENABLED=true
VITE_APP_TITLE=Certd
VITE_APP_SLOGAN=让你的证书永不过期
VITE_APP_COPYRIGHT_YEAR=2021-2026
VITE_APP_COPYRIGHT_NAME=handfree.work
VITE_APP_COPYRIGHT_URL=https://certd.handfree.work
VITE_APP_COPYRIGHT_NAME=handsfree.work
VITE_APP_COPYRIGHT_URL=https://certd.handsfree.work
VITE_APP_LOGO=static/images/logo/logo.svg
VITE_APP_LOGIN_LOGO=static/images/logo/rect-black.svg
VITE_APP_PROJECT_PATH=https://github.com/certd/certd
@@ -14,7 +14,7 @@ export default {
default: undefined,
},
},
emits: ["update:modelValue", "selected-change", "change"],
emits: ["update:modelValue", "selected-change"],
setup(props: any, ctx: any) {
const options = ref<any[]>([]);
@@ -33,8 +33,7 @@ export default {
// if (props.modelValue == null && options.value.length > 0) {
// ctx.emit("update:modelValue", options.value[0].value);
// }
//这里需要一个第一次的selected-change事件,外部表单字段有情况会用到选中的option
onSelectedChange(props.modelValue, true);
onSelectedChange(props.modelValue);
}
onCreate();
@@ -42,12 +41,9 @@ export default {
ctx.emit("update:modelValue", value);
onSelectedChange(value);
}
function onSelectedChange(value: any, isFirst: boolean = false) {
function onSelectedChange(value: any) {
if (value) {
const option = options.value.find(item => item.value == value);
if (!isFirst) {
ctx.emit("change", value);
}
if (option) {
ctx.emit("selected-change", option);
return;
@@ -4,7 +4,7 @@ export default {
"The domain name configured here serves as a proxy for verifying other domains. When other domains apply for certificates, they map to this domain via CNAME for ownership verification. The advantage is that any domain can apply for a certificate this way without providing an AccessSecret.",
cnameLinkText: "CNAME principle and usage instructions",
cnameDomain: "CNAME Domain",
cnameDomainPlaceholder: "cname.handfree.work",
cnameDomainPlaceholder: "cname.handsfree.work",
cnameDomainHelper:
"Requires a domain registered with a DNS provider on the right (or you can transfer other domain DNS servers here).\nOnce the CNAME domain is set, it cannot be changed. It is recommended to use a first-level subdomain.",
cnameDomainPattern: "Domain name cannot contain *",
@@ -3,7 +3,7 @@ export default {
cnameDescription: "此处配置的域名作为其他域名校验的代理,当别的域名需要申请证书时,通过CNAME映射到此域名上来验证所有权。好处是任何域名都可以通过此方式申请证书,也无需填写AccessSecret。",
cnameLinkText: "CNAME功能原理及使用说明",
cnameDomain: "CNAME域名",
cnameDomainPlaceholder: "cname.handfree.work",
cnameDomainPlaceholder: "cname.handsfree.work",
cnameDomainHelper: "需要一个右边DNS提供商注册的域名(也可以将其他域名的dns服务器转移到这几家来)。\nCNAME域名一旦确定不可修改,建议使用一级子域名",
cnameDomainPattern: "域名不能使用星号",
cnameProviderSubdomain: "托管子域名",
@@ -172,9 +172,9 @@ function useStepForm() {
const stepTypeSelected = (item: any) => {
if (item.needPlus && !settingStore.isPlus) {
message.warn("此插件需要开通Certd专业版才能使用");
message.warn("此插件需要开通专业版才能使用");
mitter.emit("openVipModal");
throw new Error("此插件需要开通Certd专业版才能使用");
throw new Error("此插件需要开通专业版才能使用");
}
currentStep.value.type = item.name;
currentStep.value.title = item.title;
+1 -1
View File
@@ -13,7 +13,7 @@ typeorm:
#plus:
# server:
# baseUrl: 'https://api.ai.handfree.work'
# baseUrl: 'https://api.ai.handsfree.work'
plus:
server:
+1 -1
View File
@@ -14,7 +14,7 @@ typeorm:
#plus:
# server:
# baseUrl: 'https://api.ai.handfree.work'
# baseUrl: 'https://api.ai.handsfree.work'
plus:
server:
@@ -71,7 +71,7 @@ input:
},
}
helper: 你在七牛云上配置的CDN加速域名,比如:certd.handfree.work
helper: 你在七牛云上配置的CDN加速域名,比如:certd.handsfree.work
order: 0
output: {}
pluginType: deploy
@@ -10,7 +10,7 @@ desc: 自动部署域名证书至七牛云KODO,注意是自定义源站域名
input:
domainName:
title: 自定义源站域名
helper: 你在七牛云上配置的OSS域名,比如:certd.handfree.work
helper: 你在七牛云上配置的OSS域名,比如:certd.handsfree.work
required: true
order: 0
cert:
@@ -60,7 +60,7 @@ export class SysPlusController extends BaseController {
// const bindUrl = 'http://127.0.0.1:7001/';
// const service = new PlusRequestService({
// subjectId: subjectId,
// plusServerBaseUrls: ['https://api.ai.handfree.work'],
// plusServerBaseUrls: ['https://api.ai.handsfree.work'],
// });
// const body = { subjectId, appKey: 'kQth6FHM71IPV3qdWc', url: bindUrl };
//
@@ -11,7 +11,7 @@ import { PipelineEntity } from "../../../modules/pipeline/entity/pipeline.js";
const pipelineExample = `
// 流水线配置示例,实际传送时要去掉注释
{
"title": "handfree.work证书自动化", //标题
"title": "handsfree.work证书自动化", //标题
"runnableType": "pipeline", //类型,固定为pipeline
"projectId": 1, // 项目ID 未开启企业模式,无需传递
"type": "cert", // 流水线类型,cert:证书自动化, custom :自定义流水线
@@ -28,12 +28,12 @@ describe("DnsPersistRecordService", () => {
const service = new DnsPersistRecordService();
const record = await service.buildRecord({
domain: "aaa.handfree.work",
domain: "aaa.handsfree.work",
accountUri: "https://example.com/acct/1",
});
assert.equal(record.hostRecord, "_validation-persist.aaa");
assert.equal(record.mainDomain, "handfree.work");
assert.equal(record.mainDomain, "handsfree.work");
assert.equal(record.recordValue, "letsencrypt.org; accounturi=https://example.com/acct/1; policy=wildcard");
});
@@ -160,13 +160,9 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
onSelectedChange: ctx.compute(({form})=>{
return ($event)=>{
form.dnsProviderAccessType = $event.accessType
form.dnsProviderAccess = null
}
}),
onChange: ctx.compute(({form})=>{
return ($event)=>{
form.dnsProviderAccess = null
}
}),
})
},
}
`,
@@ -32,7 +32,7 @@ export class CertApplyLegoPlugin extends CertApplyBasePlugin {
// vModel: "value",
// options: [
// { value: "https://acme-v02.api.letsencrypt.org/directory", label: "Let's Encrypt" },
// { value: "https://letsencrypt.proxy.handfree.work/directory", label: "Let's Encrypt代理,letsencrypt.org无法访问时使用" },
// { value: "https://letsencrypt.proxy.handsfree.work/directory", label: "Let's Encrypt代理,letsencrypt.org无法访问时使用" },
// ],
// },
// required: true,
@@ -47,53 +47,7 @@ export class HipmDnsmgrAccess extends BaseAccess {
}
/**
* 获取域名 ID(双层查询策略)
* 方案1: 使用 keyword 参数直接查询(高效)
* 方案2: 列表匹配作为冗余(兼容旧版本 API)
*/
async getDomainId(domainName: string): Promise<string> {
this.ctx.logger.info(`[HiPM DNSMgr] 尝试通过keyword查询域名: ${domainName}`);
// 方案1: 使用 keyword 参数直接查询
try {
const resp = await this.doRequest({
method: 'GET',
path: '/domains',
params: {
page: 1,
pageSize: 1,
keyword: domainName,
},
});
// 检查是否找到精确匹配的域名
if (resp && Array.isArray(resp) && resp.length > 0) {
const domain = resp.find((item: any) => item.name === domainName);
if (domain) {
this.ctx.logger.info(`[HiPM DNSMgr] 通过keyword查询成功: domain=${domainName}, id=${domain.id}`);
return String(domain.id);
}
}
} catch (error: any) {
this.ctx.logger.warn(`[HiPM DNSMgr] keyword查询失败,尝试列表匹配: ${error.message}`);
}
// 方案2: 如果 keyword 查询未找到,使用列表匹配作为冗余
this.ctx.logger.info(`[HiPM DNSMgr] keyword查询未找到,尝试列表匹配: ${domainName}`);
const domainList = await this.getDomainList();
const domainInfo = domainList.find((item: any) => item.domain === domainName);
if (!domainInfo) {
throw new Error(`[HiPM DNSMgr] 未找到域名:${domainName}`);
}
this.ctx.logger.info(`[HiPM DNSMgr] 通过列表匹配成功: domain=${domainName}, id=${domainInfo.id}`);
return String(domainInfo.id);
}
/**
* 获取域名列表(保留用于向后兼容)
* 获取域名列表
*/
async getDomainList() {
this.ctx.logger.info(`[HiPM DNSMgr] 获取域名列表`);
@@ -27,9 +27,6 @@ export class HipmDnsmgrDnsProvider extends AbstractDnsProvider<{ domainId: strin
const { fullRecord, hostRecord, value, type, domain } = options;
this.logger.info("[HiPM DNSMgr] 添加域名解析:", fullRecord, value, type, domain);
// 1. 获取域名 ID(双层查询策略)
const domainId = await this.access.getDomainId(domain);
this.logger.debug('[HiPM DNSMgr] 找到域名:', domain, 'ID:', domainId);
// 1. 获取域名列表,找到对应的域名 ID
const domainList = await this.access.getDomainList();
const domainInfo = domainList.find((item: any) => item.domain === domain);
@@ -132,7 +132,7 @@ export class HostDeployToIIS extends AbstractPlusTaskPlugin {
*
* SiteName HttpsBindings
* -------- -------------
* first *:443:first.handfree.work
* first *:443:first.handsfree.work
*/
// 解析获取网站名称
const siteOptions = [];
@@ -118,7 +118,7 @@ export class CtyunDeployToCDN extends AbstractTaskPlugin {
const domain_details = res.domain_details;
const errorMessage = "";
for (const domainDetail of domain_details) {
// "code":200002,"domain":"ctyun.handfree.work","message":"参数cert_name只在https_status为on时才有效"}
// "code":200002,"domain":"ctyun.handsfree.work","message":"参数cert_name只在https_status为on时才有效"}
if (domainDetail.code !== 100000) {
const thisMessage = `部署失败[${domainDetail.code}]${domainDetail.domain}:${domainDetail.message}`;
if (thisMessage.includes("已有进行中的工单") || errorMessage.includes("域名正在操作中")) {
@@ -47,7 +47,7 @@ export class QiniuDeployCertToCDN extends AbstractTaskPlugin {
@TaskInput(
createRemoteSelectInputDefine({
title: "CDN加速域名",
helper: "你在七牛云上配置的CDN加速域名,比如:certd.handfree.work",
helper: "你在七牛云上配置的CDN加速域名,比如:certd.handsfree.work",
rules: [{ type: "domains", allowDotStart: true }],
action: QiniuDeployCertToCDN.prototype.onGetDomainList.name,
required: true,
@@ -17,7 +17,7 @@ import { QiniuAccess, QiniuClient } from "../../plugin-lib/qiniu/index.js";
export class QiniuDeployCertToOSS extends AbstractTaskPlugin {
@TaskInput({
title: "自定义源站域名",
helper: "你在七牛云上配置的OSS域名,比如:certd.handfree.work",
helper: "你在七牛云上配置的OSS域名,比如:certd.handsfree.work",
required: true,
})
domainName!: string;
@@ -157,7 +157,7 @@ export class UCloudDeployToCDN extends AbstractTaskPlugin {
}
/**
* "Domain": "ucloud.certd.handfree.work",
* "Domain": "ucloud.certd.handsfree.work",
"DomainId": "ucdn-1kwdtph5ygbb"
*/
const options = list.map((item: any) => {
@@ -119,7 +119,7 @@ export class UCloudDeployToWaf extends AbstractTaskPlugin {
}
/**
* "Domain": "ucloud.certd.handfree.work",
* "Domain": "ucloud.certd.handsfree.work",
"DomainId": "ucdn-1kwdtph5ygbb"
*/
const options = list.map((item: any) => {
@@ -112,7 +112,7 @@ certificateKey
}
/**
* "Domain": "ucloud.certd.handfree.work",
* "Domain": "ucloud.certd.handsfree.work",
"DomainId": "ucdn-1kwdtph5ygbb"
*/
const options = list.map((item: any) => {