Commit Graph
4747 Commits
Author SHA1 Message Date
xiaojunnuo 5563abb13a fix: 修复证书插件配置无法打开的bug 2026-09-12 19:13:23 +08:00
xiaojunnuo 51e83e4c38 fix: 修复添加步骤会修改所有步骤标题的bug 2026-09-12 18:51:53 +08:00
xiaojunnuo 2b1a5296fe chore(certd-client): fix step form save data overwritten issue and add no payment tip
1. 修复步骤表单保存时因复用reactive对象导致已保存步骤被覆盖的问题,深拷贝currentStep后再传出
2. 新增无支付方式时显示暂不支持在线支付的提示
2026-09-12 18:49:24 +08:00
xiaojunnuo bded368cbb perf: 新增余额管理,管理员充值功能
1. 新增余额管理页面,支持用户余额查询与充值
2. 新增余额变更记录页面,查看用户余额明细
3. 补充多语言国际化文案
4. 修复免费订单显示文案为0元而非免费
5. 隐藏审核页面的操作按钮
6. 注释掉无用的堆日志启动代码
2026-09-12 16:06:53 +08:00
xiaojunnuo 6a649aaca0 perf(acme-account-access): AcmeAccount授权允许修改eab,重新生成account
修改了三处ACME账号表单的禁用判断条件,新增判断当editAccount为true时不禁用控件,允许在编辑已有账号时修改相关配置
2026-09-12 14:44:43 +08:00
xiaojunnuo e971145686 perf(ui): 商业版套餐购买不要求设置支付方式
1. 将套餐设置页面的"需要开启支付方式"提示改为"建议"
2. 新增支付方式为空且余额不足时的红色警告提示
3. 默认开启返利余额使用并修复支付字典加载异常处理
2026-09-12 14:28:52 +08:00
xiaojunnuo bbca449f94 Merge branch 'v2-dev' of https://github.com/certd/certd into v2-dev 2026-09-12 09:32:36 +08:00
xiaojunnuo e6852c2715 docs: 更新AGENTS.md编码规范说明
refactor(plugin-fastly): 简化多行API调用代码
refactor(plugin-serv
2026-09-11 19:01:29 +08:00
xiaojunnuo 47cb523307 chore(cloudflare): 优化权限说明的换行展示
修复Cloudflare插件的权限说明文本排版,将权限项用换行分开展示,提升可读性
2026-09-10 15:13:38 +08:00
xiaojunnuo cbf46b5c48 build: release 2026-09-07 00:07:49 +08:00
xiaojunnuo 7ed3105d97 build: publish 2026-09-06 23:51:23 +08:00
xiaojunnuo 61b945c08f build: trigger build image 2026-09-06 23:51:13 +08:00
xiaojunnuo cc60cd4cd1 v1.44.3 v1.44.3 2026-09-06 23:50:28 +08:00
xiaojunnuo dade599acb build: prepare to build 2026-09-06 23:46:14 +08:00
xiaojunnuo 1070417a36 chore: 修复fastly 通配符型号转换格式的问题 2026-09-06 23:45:56 +08:00
xiaojunnuo 81f676f1ca build: prepare to build 2026-09-06 23:29:25 +08:00
xiaojunnuo 0cf0608d3f build: prepare to build 2026-09-06 23:25:52 +08:00
xiaojunnuo dac94b64f0 fix(plugin-service): 修复同步自己开发的云端插件不显示已安装状态问题
将开发者ID、VIP状态、依赖插件、AI检查状态、插件状态、应用ID和作者字段加入插件更新逻辑,完善插件信息同步的完整性
2026-09-06 23:08:31 +08:00
xiaojunnuo 8c88092235 docs: 优化docker镜像文档的排版和内容
调整了README和docker安装指南中的镜像说明部分,将原有的零散说明改为表格形式统一展示,修正了镜像地址的展示位置,补充了稳定版slim/armv7的完整镜像地址信息,清理了重复的说明内容。
2026-09-06 17:28:00 +08:00
Steven ZhuandClaude Sonnet 5 2a2e963914 perf(plugin): add Fastly custom TLS certificates integration (#797) @szhu25
* feat(plugin): add Fastly custom TLS certificates integration

Introduces a complete set of Fastly plugins for automating custom TLS certificates deployment:
- `FastlyAccess`: Handles Fastly API authentication and provides helpers for dynamic data fetching (Services, Domains, Configs).
- `FastlyUploadCert`: Uploads a new private key and certificate (2-step POST process) or updates an existing one (PATCH).
- `FastlyDeployCert`: Activates a custom TLS certificate by linking it to a TLS configuration and domain via TLS Activations API.
- `FastlyRefreshCert`: Bulk updates existing custom TLS certificates.
- `FastlyPurgeCache`: Purges all cache for a specified Fastly Service.

Includes comprehensive unit tests covering API request formats and error handling for all tasks.

* fix(fastly): drop invalid 'multiple' option from refresh-cert input define

createRemoteSelectInputDefine has no 'multiple' option; multi-select is
already its default (mode: "tags", single: false). The excess property
broke the production build (TS2353).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015dRf6EbAmwb37cpnvgBDrh

* fix(fastly): correct TLS list unwrapping, paginate, harden purge

- access: ctx.http already unwraps to the response body, so the JSON:API
  item array is at body.data, not body.data.data — getTlsConfigurations /
  getTlsDomains / getCertificates always returned [] and the selectors
  were empty. Fetch via listAllJsonApi, which also pages past Fastly's
  20-item default so accounts with more than one page are fully listed.
- purge-cache: send no body to /purge_all (auth is header-only) instead
  of an empty JSON:API object.
- upload-cert / refresh-cert: note in the helper text that Fastly requires
  the renewed cert to reuse the original private key for PATCH updates.
- test: cover the list-helper unwrapping, pagination aggregation, and the
  bare-array /service response.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015dRf6EbAmwb37cpnvgBDrh

* fix(fastly): use output-selector for deploy cert ID input

The FastlyDeployCert `certificateId` input was a free-text box whose
helper pointed users at a non-existent "advanced settings" workflow to
grab the upstream output variable. certd only surfaces a prior step's
@TaskOutput through an input whose component is `output-selector`, so the
FastlyUploadCert `fastlyCertId` output was never selectable.

Bind the input to `output-selector` with `from: ["FastlyUploadCert"]`,
matching the pattern used by plugin-aliyun deploy-to-cdn.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFPQmZU9uvAfR9jHgaPP9J

* fix(fastly): accept cert or uploaded id in deploy, share upload helpers

Rework FastlyDeployCert to mirror the AWS CloudFront pattern instead of
demanding a hand-typed / separately-uploaded certificate id:

- The `certificateId` text box (and the earlier FastlyUploadCert-only
  output-selector) is replaced by a `cert: CertInfo | string` input whose
  output-selector accepts both a cert-apply step's cert and a
  FastlyUploadCert step's `fastlyCertId`.
- execute() binds the id directly when it got a string; when it got a raw
  CertInfo it uploads to Fastly first (new optional `name` input), then
  creates the TLS activation. So a plain "apply cert -> activate" pipeline
  needs no separate upload step.

Extract the Fastly certificate create (2-step key + cert) and update
(PATCH) flows into FastlyAccess.createCertificate / updateCertificate and
reuse them from both FastlyUploadCert and FastlyDeployCert.

Tests updated to drive the plugins through a real FastlyAccess with only
doRequestApi stubbed; added a deploy case for the raw-CertInfo path.

Note: build/tests not run locally (no Node toolchain on this machine) —
needs CI / local verification.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFPQmZU9uvAfR9jHgaPP9J

* fix(fastly): reuse existing key/cert when Fastly reports "already exists"

Fastly deduplicates TLS private keys (and byte-identical certificates) by
content, so re-running an upload fails with 400 "... already exists:
'<id>'". Recover that id and carry on instead of aborting:

- ensurePrivateKey(): on "already exists", parse the id from the error
  (or match an existing key by name), else throw actionable guidance.
- createCertificate(): same treatment for the /tls/certificates POST;
  when no id is recoverable, tell the user to supply the certificate id
  so the PATCH (update) path is used.
- Shared FastlyAccess.extractExistingId() helper.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFPQmZU9uvAfR9jHgaPP9J

* fix(fastly): per-domain TLS activation, idempotent on renewal

The TLS 域名 / TLS 配置 selectors use createRemoteSelectInputDefine, which
defaults to multi-select ("tags"), so domainId arrived as an array and was
written straight into tls_domain.data.id -> Fastly 500. A tls_activation
also binds exactly one domain, so wildcard + apex needs one each.

- domainId -> domainIds (string[]); loop, one activation per domain.
  configurationId gets single:true; both inputs are still normalised in
  execute() (array-or-scalar, plus legacy `domainId` key).
- New FastlyAccess.deployActivation(): looks up an existing activation for
  the domain+configuration and PATCHes it onto the new certificate;
  otherwise POSTs a fresh one. Renewals no longer fail on a duplicate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFPQmZU9uvAfR9jHgaPP9J

* feat(fastly): list service domains for TLS activation, not cert SANs

The TLS 域名 selector was populated from GET /tls/domains, which only
echoes certificate SAN entries — so a wildcard cert offered "*.g0l.net",
which cannot be activated unless a service actually serves that wildcard.

onGetTlsDomainList now lists the domains configured on the active version
of each Fastly service (new FastlyAccess.getServiceDomains()), which are
the names you can actually activate (e.g. www.g0l.net, covered by the
wildcard). Cert-derived TLS domains are still appended, tagged "(来自证书)".
The field stays free-entry so an unlisted host can be typed in.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFPQmZU9uvAfR9jHgaPP9J

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 16:20:14 +08:00
Steven ZhuandClaude Sonnet 5 1b882a2ca4 AWS ratelimit fix (#796) @szhu25
* Parse PEM chain and import certificate chain

Split the PEM in certInfo.crt into a leaf certificate and intermediate chain (using a lookbehind regex), trim the blocks, and pass the chain to ImportCertificateCommand only when present. Replace console.log with this.logger.info and log the returned CertificateArn. This ensures the leaf cert is uploaded separately from its chain and avoids sending an empty CertificateChain.

* Add AWS retry & CloudFront deployment wait

Introduce robust retry and polling helpers to handle AWS throttling and CloudFront propagation. Added AwsClient.withRetry (exponential backoff, handles common throttling errors, default 5 attempts/base 2s) and waitForDistributionDeployed (polls until distribution Status is "Deployed", default 10min timeout/15s interval). Update deploy-to-cloudfront plugin to use withRetry for Get/UpdateDistribution and importCertificate, pass AwsClient into uploadToACM, and wait for each distribution to finish deploying before continuing to avoid PreconditionFailed errors. Improves reliability when facing rate limits and global CloudFront propagation delays; adds informative logging for retry and deployment status.

* fix(aws): resolve rate limit and runtime import bugs

* fix(aws): broaden retry detection and harden CloudFront poll

- withRetry: retry on Route53 PriorRequestNotComplete, SlowDown, SDK v3
  $retryable.throttling hints and HTTP 429/503; extract detection into
  isRetryableAwsError
- withRetry: add equal jitter to backoff so concurrent pipelines don't
  retry in lockstep
- waitForDistributionDeployed: a throttle that outlives withRetry's budget
  keeps polling until the deadline instead of aborting the deploy
- test: cover withRetry retry/exhaustion/non-throttle paths

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015dRf6EbAmwb37cpnvgBDrh

* fix(aws): fix build break and make withRetry the sole retry authority

- withRetry<T = any>: default the type param so call sites passing an
  untyped SDK client (@aws-sdk/* is a lazyDependency with no build-time
  types) don't collapse the result to `unknown`. Also annotate the two
  result consumers as `any`. Fixes the TS2339 errors that broke the
  Docker build (aws-client.ts, plugin-deploy-to-cloudfront.ts).
- Set maxAttempts: 1 on every AWS SDK client (ACM/STS/Route53/CloudFront)
  so the SDK's own retry strategy no longer stacks on top of withRetry.
- isRetryableAwsError: broaden to cover what the SDK's `standard` strategy
  used to handle now that it's disabled - $retryable hint, HTTP 429 + any
  5xx, connection-level errors (ECONNRESET/ETIMEDOUT/EAI_AGAIN/...).
- waitForDistributionDeployed: a transient error that outlives withRetry's
  budget now retries on the next poll instead of aborting the whole deploy.
- test: cover 5xx, $retryable, and connection-error retry paths.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BrMVmQyvQjes6t4DGjuBaD

* feat(aws): make CloudFront deploy-wait opt-in (default off)

Polling GetDistribution until Status=Deployed adds 3-8min of pipeline
wall-time per run for no functional gain - CloudFront finishes the
rollout on its own once UpdateDistribution returns 200. Gate it behind
a new "等待部署完成" switch, default false. Retry/backoff on the actual
mutating calls (GetDistributionConfig / UpdateDistribution / ACM import
/ Route53) is unaffected - it wraps those sends directly, not the poll.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BrMVmQyvQjes6t4DGjuBaD

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 16:19:47 +08:00
xiaojunnuo bd9433478a fix(plugin): 修复插件配置保存与加载的相关问题
1.  修复插件配置保存时使用fullName或name作为标识的问题
2.  为证书申请插件配置补充pluginType字段
3.  新增插件配置全局加载逻辑,启动时同步数据库插件配置到内存注册表
4.  优化配置编辑器默认值与选项添加交互
5.  补充vue依赖导入与上下文注入
2026-09-05 00:27:26 +08:00
xiaojunnuo 32ade8e4a3 build: release 2026-09-03 22:16:49 +08:00
xiaojunnuo f2bcdeeb33 build: publish 2026-09-03 22:05:17 +08:00
xiaojunnuo 4099af7f5d build: trigger build image 2026-09-03 22:05:07 +08:00
xiaojunnuo 67f3daae62 v1.44.2 v1.44.2 2026-09-03 22:04:19 +08:00
xiaojunnuo c72fa68e4c build: prepare to build 2026-09-03 21:57:56 +08:00
xiaojunnuo 1f5cda452c test(cert): 修复DNS持久化记录服务测试用例的查询方法适配问题
将测试中使用的findOneBy替换为标准的findOne方法,适配服务层实际的查询逻辑,修正测试用例的模拟实现
2026-09-03 21:57:47 +08:00
xiaojunnuo 5a19d2513d build: prepare to build 2026-09-03 21:49:35 +08:00
xiaojunnuo c0f8145615 test(plugin-service): 完善插件服务测试用例
修复并补充插件安装相关的单元测试逻辑,新增findOne仓库方法模拟,校验查询参数正确性,调整断言逻辑以匹配实际的查询次数
2026-09-03 21:49:15 +08:00
xiaojunnuo 2ad14b82fa chore(base-service): 修复findOneBy方法调用不兼容的问题
将弃用的findOneBy替换为标准的findOne查询方式,兼容新版本的TypeORM接口
2026-09-03 21:37:52 +08:00
xiaojunnuo c8bdcdc778 build: prepare to build 2026-09-03 21:20:43 +08:00
xiaojunnuo 15d2bd8484 fix: 修复插件市场插件安装无效的bug 2026-09-03 21:20:17 +08:00
xiaojunnuo 7d4311115c chore(plugin-service): 补全内置插件的installed字段赋值逻辑
为内置插件添加默认的installed状态设置,统一插件安装状态的处理逻辑,修复部分场景下插件安装状态不准确的问题
2026-09-03 01:39:22 +08:00
xiaojunnuo 3efa0582ef Merge branch 'v2-dev' into v2 2026-09-03 01:17:35 +08:00
xiaojunnuo 7624babc99 build: release 2026-09-03 01:17:10 +08:00
xiaojunnuo 6cf8f350f5 build: publish 2026-09-03 00:58:57 +08:00
xiaojunnuo 0e08555220 build: trigger build image 2026-09-03 00:58:47 +08:00
xiaojunnuo fe738fa7d4 v1.44.1 v1.44.1 2026-09-03 00:50:48 +08:00
xiaojunnuo 2439f4ab02 build: prepare to build 2026-09-03 00:44:44 +08:00
xiaojunnuo 75b2b146ce test: 优化两个测试文件的代码结构与测试逻辑
1.  为证书信息服务测试提取复用的服务创建函数,减少重复代码
2.  修复插件服务测试用例,修正作者校验逻辑、同步逻辑、插件导入更新等多处测试断言
2026-09-03 00:43:53 +08:00
xiaojunnuo 1f3c096517 build: prepare to build 2026-09-03 00:22:26 +08:00
xiaojunnuo d264388c00 build: prepare to build 2026-09-03 00:17:04 +08:00
xiaojunnuo b8eaeeaa64 refactor(plugin-service): 调整在线插件作者请求的必填字段
将name和email从必填改为可选字段,优化接口参数灵活性
2026-09-03 00:16:59 +08:00
xiaojunnuo dba1a486cb chore(ui/certd-server): update metadata config and fix event name
1. 修正deploy_CertApply.yaml中DNS持久验证的说明文本
2. 将表单的selected-change事件名改为驼峰式selectedChange
3. 为acmeAccount的选择组件添加emitImmediate配置
2026-09-03 00:15:49 +08:00
xiaojunnuo 5408ae6ad8 build: prepare to build 2026-09-03 00:08:37 +08:00
Atirna f5430a8925 fix: preserve Route53 TXT record values (#791) 2026-09-02 23:59:45 +08:00
xiaojunnuo 9cc21204b1 docs(install/docker): update mirror table and add aliyun registry tags
1. 补全docker镜像表格的分隔线对齐格式
2. 在release镜像工作流中新增阿里云certd镜像仓库的推送标签
2026-09-02 22:42:25 +08:00
xiaojunnuo f911e06a69 fix: 修复大量问题
1.  更新多处文案,将"仅Let's Encrypt"改为"仅Let's Encrypt 测试环境"
2.  新增getSiteId方法到设置store
3.  优化项目store缓存key和变量声明顺序
4.  重构插件作者字段组件:添加作者注册状态管理、禁用输入框、支持修改邮箱
5.  暴露updatePluginAuthorEmail方法并完善插件类型注释
6.  调整首页统计卡片布局位置
7.  移除多余空行和注释掉Addon插件类型选项
2026-09-01 23:21:06 +08:00
xiaojunnuo 4a6eab0ce6 refactor(plugin): 调整插件相关代码结构与逻辑
1. 为createRemoteSelectInputDefine新增emitImmediate参数
2. 新增BaseService.updateById方法简化更新操作
3. 移除插件服务中多余的YAML序列化工具方法,改为前端处理
4. 优化插件更新、同步逻辑,替换部分update调用为updateById
5. 简化插件作者校验逻辑
2026-09-01 20:53:50 +08:00