mirror of
https://github.com/certd/certd.git
synced 2026-10-14 01:46:00 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c98b974f7 | ||
|
|
e2aff952f9 | ||
|
|
9d9ae64aff | ||
|
|
22715a430e | ||
|
|
949a69f0dc | ||
|
|
53db97b6f2 | ||
|
|
cd2dcaa859 | ||
|
|
d0463abc26 | ||
|
|
8f1b38ad7d | ||
|
|
e11349b8cc | ||
|
|
2394cc6dd9 | ||
|
|
8209c3d6e1 | ||
|
|
3e001b8ba4 | ||
|
|
41ca198116 | ||
|
|
6eca5dad9b | ||
|
|
c285522500 | ||
|
|
b12f7c54d4 | ||
|
|
b055bbecfc | ||
|
|
a52a6ce8f6 | ||
|
|
fcbf1045fe | ||
|
|
f5cfe054b7 | ||
|
|
5ded5ff2b6 | ||
|
|
8d31346cd3 | ||
|
|
44b41b6a08 | ||
|
|
4420472f8f | ||
|
|
c4497a7018 | ||
|
|
03f1a7bd0e | ||
|
|
97d2b50074 | ||
|
|
2d0b85b305 | ||
|
|
28052c9387 | ||
|
|
c4277350bc | ||
|
|
97160373d6 | ||
|
|
0ce24618a1 | ||
|
|
f60e63fbaf | ||
|
|
2735feb330 | ||
|
|
b6381d79fc | ||
|
|
241b2e5584 | ||
|
|
bb1f232f41 | ||
|
|
f82d3a5fcc | ||
|
|
bbeaf617d1 | ||
|
|
ea7d14c289 | ||
|
|
3272a68ff6 | ||
|
|
b5715d99ff | ||
|
|
3f5ba14fde | ||
|
|
07f0d3b4d6 | ||
|
|
3dbbe72fc1 | ||
|
|
7f006d1359 | ||
|
|
d30f1c4785 | ||
|
|
96e0122b93 | ||
|
|
7786a87b21 | ||
|
|
34476ba14f | ||
|
|
4b942385a8 |
@@ -3,7 +3,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "版本号(如 v1.42.5)"
|
||||
description: "版本号(如 1.42.5)"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
|
||||
+2
-1
@@ -42,4 +42,5 @@ output/
|
||||
.uploads/
|
||||
.certd-plugin-history/
|
||||
.tmp
|
||||
.plugin-dev/
|
||||
.plugin-dev/
|
||||
.tmp_chunks/
|
||||
@@ -23,6 +23,8 @@ version: 1.0.0
|
||||
|
||||
- 配置插件的唯一标识、标题、图标和描述
|
||||
- 继承 `BaseAccess` 类
|
||||
- 插件默认文案使用中文;需要英文时,在注解参数对象中添加同级 `i18n: { "en-US": { ... } }`,不要写成 `metadata.i18n`。`define` 本身就是插件 metadata。
|
||||
- `i18n["en-US"]` 仅配置要翻译的展示字段,如 `title`、`desc`、`input`;输入字段可翻译 `title`、`helper`、组件展示文案和 `optionsMapping`。缺少英文翻译时回退默认中文。
|
||||
|
||||
3. **定义授权属性**
|
||||
|
||||
@@ -392,6 +394,66 @@ export class OAuthDemoAccess extends BaseAccess {
|
||||
}
|
||||
```
|
||||
|
||||
## 字段动态显隐(mergeScript)
|
||||
|
||||
多种鉴权方式共用一个授权时,用 `@AccessInput` 上的 `mergeScript` 按所选方式显隐字段:
|
||||
|
||||
```typescript
|
||||
@AccessInput({
|
||||
title: '鉴权方式',
|
||||
value: 'apikey',
|
||||
component: {
|
||||
name: 'a-select',
|
||||
vModel: 'value',
|
||||
options: [
|
||||
{ label: 'AccessKey签名', value: 'aksk' },
|
||||
{ label: 'ApiKey', value: 'apikey' },
|
||||
],
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
authType = 'apikey';
|
||||
|
||||
@AccessInput({
|
||||
title: 'accessKeyId',
|
||||
component: { name: 'a-input', vModel: 'value' },
|
||||
required: true,
|
||||
mergeScript: `
|
||||
return {
|
||||
show: ctx.compute(({form})=>{
|
||||
return !form.access.authType || form.access.authType === 'aksk';
|
||||
})
|
||||
}
|
||||
`,
|
||||
})
|
||||
accessKeyId = '';
|
||||
```
|
||||
|
||||
要点:
|
||||
|
||||
- `mergeScript` 返回的对象会深合并进本字段定义,可动态化的属性有 `show`、`required`、`helper`、
|
||||
`component` 下的属性(`options`、`placeholder` 等)以及 `component.on` 事件。
|
||||
- **动态判断必须写在 `ctx.compute(({form})=>{ ... })` 回调里**。`mergeScript` 本身在插件类
|
||||
定义阶段就被拼成字符串,那时表单还没打开,用参数在服务端判断字段值没有意义。
|
||||
- 授权表单字段值在 `form.access.xxx`(任务表单才是 `form.xxx`)。
|
||||
- 历史授权没有新字段,条件里要用 `!form.access.authType || ...` 兜底走旧逻辑,保证老授权还能编辑保存。
|
||||
- 联动其他字段用 `component.on` 事件回调,回调参数是 `{ form }`:
|
||||
|
||||
```typescript
|
||||
mergeScript: `
|
||||
return {
|
||||
component: {
|
||||
on: {
|
||||
selectedChange: (scope) => {
|
||||
const form = scope.form;
|
||||
form.acmeAccountAccessId = null;
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`,
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **插件命名**:插件名称应简洁明了,反映其功能。
|
||||
|
||||
@@ -9,7 +9,7 @@ description: 用于通过 Certd API 开发、修改、读取、保存和恢复
|
||||
|
||||
本 Skill 使用 Certd HTTP API,不使用 WebSocket,也不依赖浏览器传递代码草稿。
|
||||
|
||||
- 前端只生成包含需求、API 地址和认证 Token 的启动提示词。
|
||||
- 前端只生成包含需求、插件作者、API 地址和认证 Token 的启动提示词。
|
||||
- Agent 直接调用 Certd API 读取和保存插件 YAML。
|
||||
- Agent 的进度、日志和代码修改在 Codex/Trae 中查看。
|
||||
- 插件开发临时文件和修改历史统一保存在 Agent 工作区的 `.plugin-dev/` 下,不保存到浏览器或 Certd 后端。
|
||||
@@ -43,15 +43,13 @@ Certd 插件按来源分为三类:
|
||||
|
||||
## API 认证
|
||||
|
||||
提示词会提供 Certd API 地址和仅限 AI 插件开发接口的受限 Token。调用 API 时使用:
|
||||
提示词会提供 Certd API 地址和仅限 AI 插件开发接口的受限的短时效的 Token。调用 API 时使用:
|
||||
|
||||
```http
|
||||
Authorization: <token>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
不要把 Token 写入代码、历史摘要、日志、提交信息或插件 YAML。
|
||||
|
||||
所有 Certd API 请求统一使用 Node.js 的 `fetch`。不要使用 PowerShell 的 `Invoke-RestMethod`、`Invoke-WebRequest` 或 .NET HTTP 客户端发送插件 YAML/JSON;它们在 Windows 上可能造成中文乱码或使完整 YAML 导入请求长时间无响应。
|
||||
|
||||
Node 请求须直接读取 UTF-8 文件或在 Node 内构造 JSON,并使用 `JSON.stringify`:
|
||||
@@ -118,6 +116,7 @@ const response = await fetch(`${apiBase}/scoped/sys/ai/plugin/find`, {
|
||||
- 修改后保存修改摘要。
|
||||
- 恢复前再次备份当前版本。
|
||||
- 不上传历史文件,不保存 Token、证书、私钥或真实授权值。
|
||||
- 修改完一版后立即提交更新到certd,但不要发布到市场。
|
||||
|
||||
详细格式见 `references/local-history.md`。
|
||||
|
||||
@@ -125,6 +124,7 @@ const response = await fetch(`${apiBase}/scoped/sys/ai/plugin/find`, {
|
||||
|
||||
插件始终以完整 YAML 传递和保存,脚本源码放在顶层 `content` 字段。
|
||||
|
||||
- 新插件的 `author` 必须使用启动提示词中给出的插件作者,不要自行编造作者名;修改已有插件时保留原 `author`,不要改成其他作者。
|
||||
- 统一使用 `await _ctx.import(...)` 引用模块。
|
||||
- `"/@/..."` 表示以绝对路径引用 `server/src/` 下的模块。
|
||||
- 最后返回继承目标基类的 class。
|
||||
@@ -135,6 +135,28 @@ const response = await fetch(`${apiBase}/scoped/sys/ai/plugin/find`, {
|
||||
|
||||
需要字段格式时读取 `references/online-yaml-format.md`。
|
||||
需要组件示例时读取 `references/component-examples.md`。
|
||||
需要按其他字段动态显隐/必填/联动时读取 `references/merge-script.md`。
|
||||
|
||||
### 字段动态显隐(mergeScript)
|
||||
|
||||
字段定义支持 `mergeScript`:脚本 `return` 的对象会合并进本字段,用来做「选了 A 才显示 B」这类联动。
|
||||
|
||||
```yaml
|
||||
mergeScript: |2-
|
||||
|
||||
return {
|
||||
show: ctx.compute(({form})=>{
|
||||
return form.access.authType === 'apikey';
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
- 动态逻辑必须写在 `ctx.compute(({form})=>{ ... })` 回调里;`mergeScript` 本身在插件类定义阶段就
|
||||
被拼成字符串,那时表单还没打开,用参数在 node 侧判断字段值没有任何意义。
|
||||
- 授权表单字段值在 `form.access.xxx`,任务表单字段值在 `form.xxx`。
|
||||
- 新增可选字段时要给历史数据兜底,例如 `!form.access.authType || form.access.authType === 'aksk'`。
|
||||
|
||||
完整用法(能力、可动态化的属性、事件联动、常见错误、验证方式)见 `references/merge-script.md`。
|
||||
|
||||
## 示例插件
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: DemoAccess
|
||||
icon: logos:airflow-icon
|
||||
title: Demo-授权插件示例 # 模块-插件名
|
||||
title: Demo-授权插件示例 # 格式:平台-功能 ,例如: 网宿-授权 ; 阿里云-授权 ; 天翼云-授权
|
||||
group: null
|
||||
desc: 这只是一个示例
|
||||
version: 1.0.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: DemoDeploy
|
||||
icon: logos:amp-icon
|
||||
title: Demo-部署插件示例 # 模块-插件名
|
||||
title: Demo-部署插件示例 # 格式:平台-功能 ,例如: 网宿-更新CDNpro证书 ; 阿里云-上传到CAS证书管理服务 ; 天翼云-更新CDN证书
|
||||
group: cdn
|
||||
desc: 这仅仅是一个示例
|
||||
version: 1.0.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: DemoDnsProvider
|
||||
icon: fa-solid:frog
|
||||
title: Demo-Dns提供商插件示例 # 模块-插件名
|
||||
title: Demo-Dns提供商插件示例 # 格式:平台-功能 ,例如: 阿里云-DNS提供商 ;腾讯云-DNS提供商
|
||||
desc: 这只是一个示例
|
||||
type: custom
|
||||
version: 1.0.0
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
# mergeScript 用法
|
||||
|
||||
来源:前端 `packages/ui/certd-client/src/use/use-refrence.tsx`,类型定义来自 `@fast-crud/fast-crud`。
|
||||
|
||||
`mergeScript` 用来让输入字段的定义**依赖当前表单里的其他字段值动态变化**,例如:
|
||||
选了某个鉴权方式才显示对应字段、切换类型后清空已选值、下拉选项跟着另一个字段变。
|
||||
|
||||
它写成字符串放在字段定义上(内置插件放在 `@AccessInput` / `@TaskInput` 里,在线插件放在 `input.<字段>` 下):
|
||||
|
||||
```ts
|
||||
@AccessInput({
|
||||
title: "API Key",
|
||||
component: { name: "a-input", vModel: "value" },
|
||||
mergeScript: `
|
||||
return {
|
||||
show: ctx.compute(({form})=>{
|
||||
//access里面 要用 form.access.[字段名]
|
||||
return form.access.authType === 'apikey';
|
||||
//deploy插件里面要用form.[字段名]
|
||||
return form.authType === 'apikey';
|
||||
})
|
||||
}
|
||||
`,
|
||||
})
|
||||
apiKey = "";
|
||||
```
|
||||
|
||||
## 执行时机
|
||||
|
||||
字段定义被前端加载时,对**每一个字段**执行一次:
|
||||
|
||||
```js
|
||||
const func = new Function('ctx', formItem.mergeScript);
|
||||
const merged = func(ctx); // 字段脚本只执行这一次
|
||||
merge(formItem, merged); // 返回值深合并进该字段的定义
|
||||
delete formItem.mergeScript; // 执行完就删掉,最终定义里不再有 mergeScript
|
||||
```
|
||||
|
||||
要点:
|
||||
|
||||
- 脚本体内**必须 `return` 一个对象**,返回的对象会深合并到本字段的定义上。
|
||||
- 脚本本身只在加载字段时跑一次,**拿不到、也不应该判断用户填了什么值**。
|
||||
- 真正的动态逻辑写在返回对象里的 `ctx.compute(...)` 回调中,由 fast-crud 在渲染时求值。
|
||||
|
||||
## ctx 提供的能力
|
||||
|
||||
| 能力 | 说明 |
|
||||
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `ctx.compute(fn)` | 最常用。返回一个响应式的计算值:`fn` 里读到的表单字段会被自动追踪,字段变化时重新计算,视图跟着刷新 |
|
||||
|
||||
`ctx.compute` 的回调参数是一个 context 对象,常用字段:
|
||||
|
||||
- `form`:当前表单数据。**这是唯一常用的一个**。
|
||||
- `row`:行数据。
|
||||
- `mode`:表单模式 `add` / `edit` / `view`。
|
||||
- `getComponentRef(key)`:取其他字段组件的 ref。
|
||||
|
||||
注意:Certd 在把 `form` 传进回调前做过一次兼容处理(`form.input || form.body || form`),
|
||||
所以两种表单取值路径不同:
|
||||
|
||||
- **授权(Access)表单**:字段值在 `form.access.xxx`(字段 key 会被加上 `access.` 前缀)。
|
||||
- **任务(Task)表单**:字段值直接是 `form.xxx`。
|
||||
|
||||
## 可以动态化的属性
|
||||
|
||||
返回的对象里,任何字段定义属性都可以用 `ctx.compute`,常用的有:
|
||||
|
||||
| 属性 | 用途 |
|
||||
| -------------------- | ------------------------------------------------------------------------------------------------- |
|
||||
| `show` | 显隐(最常用) |
|
||||
| `required` | 动态必填,例如 `required: ctx.compute(({form}) => form.targetType === 'ingress')` |
|
||||
| `disabled` | 动态禁用,例如账号已创建后不允许再改:`disabled: ctx.compute(({form}) => !!form.access?.account)` |
|
||||
| `helper` | 动态帮助文案,回调里按条件 `return` 不同字符串 |
|
||||
| `value` | 动态默认值 |
|
||||
| `component` 下的属性 | 动态 `options`、`placeholder`、`inputKey`、`type`、`disabled` 等 |
|
||||
| `component.on` | 事件处理,见下面「联动」 |
|
||||
| `col` / `order` | 布局与排序 |
|
||||
|
||||
只写了一层 `show` 时最简形式就是本文开头的例子。
|
||||
|
||||
## 联动(监听事件并改动其他字段)
|
||||
|
||||
`component.on` 的事件回调**不**用 `ctx.compute` 包,它本身就是回调,参数是
|
||||
`{ form, $event, ... }`;`form` 同样做过 `form.input || form.body || form` 的兼容处理。
|
||||
事件名按组件而定,例如 `selectedChange`。
|
||||
|
||||
```ts
|
||||
mergeScript: `
|
||||
return {
|
||||
component: {
|
||||
on: {
|
||||
selectedChange: (scope) => {
|
||||
const form = scope.form;
|
||||
// 切换颁发机构后清空 ACME 账号,避免账号与机构不匹配
|
||||
form.acmeAccountAccessId = null;
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`,
|
||||
```
|
||||
|
||||
另一种写法是把回调也做成计算值(需要用到组件上配置的 `onSelectedChange` / `onChange` 属性):
|
||||
|
||||
```ts
|
||||
mergeScript: `
|
||||
return {
|
||||
component: {
|
||||
onSelectedChange: ctx.compute(({form}) => {
|
||||
return ($event) => {
|
||||
form.dnsProviderAccessType = $event.accessType;
|
||||
};
|
||||
}),
|
||||
},
|
||||
}
|
||||
`,
|
||||
```
|
||||
|
||||
两种写法都能用,优先参考同目录已有插件的写法,保持一致。
|
||||
|
||||
## 常见错误
|
||||
|
||||
- **不要用 node 侧变量决定条件**。`mergeScript` 是在插件类定义阶段(node 侧)拼出来的字符串,
|
||||
此时表单还没打开,拿不到任何用户输入;用参数拼条件等于把逻辑写死在服务端。
|
||||
条件必须原样落到 `ctx.compute` 回调里。
|
||||
- **不要用 `if` 直接判断字段值**。回调必须 `return` 一个值,写成
|
||||
`show: ctx.compute(({form}) => { if (...) { return true } })` 也可以,但不要漏掉 `return`。
|
||||
- **不要漏掉历史数据兼容**。新增可选字段时,历史数据里没有这个字段(值为 `undefined`),
|
||||
条件要按旧行为兜底,例如 `!form.access.authType || form.access.authType === 'aksk'`。
|
||||
- **不要访问 `form.access` 以外的路径**去读授权字段,也不要在授权表单里按任务表单的路径取值。
|
||||
- **不要依赖脚本执行时的副作用**(打印日志、改全局状态),它在每次打开表单时都会重新执行。
|
||||
|
||||
## YAML 写法(在线插件)
|
||||
|
||||
`mergeScript` 是含换行的脚本字符串,必须用 YAML 块标量:
|
||||
|
||||
```yaml
|
||||
input:
|
||||
apiKey:
|
||||
title: API Key
|
||||
component:
|
||||
name: a-input
|
||||
vModel: value
|
||||
mergeScript: |2-
|
||||
|
||||
return {
|
||||
show: ctx.compute(({form})=>{
|
||||
return form.access.authType === 'apikey';
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
导出生成的缩进比较特殊(块标量内容统一缩进),**不要手工调整缩进**:
|
||||
用脚本生成 YAML,并保证导出后再导入内容一致。转换成 block scalar 时注意:
|
||||
|
||||
- `|` / `|2-` 等块标量不需要转义换行,不要把脚本写成带 `\n` 的单行。
|
||||
- 脚本里不要出现 `??` 这类容易被误判为乱码的写法,用显式 `if (x == null)` 代替。
|
||||
|
||||
## 验证方式
|
||||
|
||||
前端表单没法在插件开发流程里直接断言,可以在后端加一个 `src/**/*.test.ts`,
|
||||
按前端 `useReference` 的路径执行字段上的 `mergeScript`:
|
||||
|
||||
```ts
|
||||
const computedGetters = [];
|
||||
const ctx = {
|
||||
compute: getter => {
|
||||
computedGetters.push(getter);
|
||||
return getter;
|
||||
},
|
||||
asyncCompute: () => undefined,
|
||||
computed: () => undefined,
|
||||
};
|
||||
new Function('ctx', mergeScript)(ctx);
|
||||
// 用假的 form 求值,断言显隐结果
|
||||
const show = computedGetters[0]({ form: { access: { authType: 'apikey' } } });
|
||||
```
|
||||
|
||||
参考实现:`packages/ui/certd-server/src/plugins/plugin-wangsu/access-input.test.ts`。
|
||||
要点是断言「同一个 show 函数换 `authType` 结果会变」,证明显隐确实是运行时算的,
|
||||
而不是在 node 侧定死的。
|
||||
@@ -7,7 +7,7 @@
|
||||
```yaml
|
||||
name: DemoTask
|
||||
author: demo
|
||||
title: Demo 任务
|
||||
title: Demo-插件名称 # 格式:平台-功能 ,例如: 网宿-更新CDNpro证书 ; 阿里云-上传到CAS证书管理服务 ; 天翼云-更新CDN证书
|
||||
desc: 插件说明
|
||||
icon: clarity:plugin-line
|
||||
pluginType: task
|
||||
@@ -61,6 +61,8 @@ content: |
|
||||
### 编辑规则
|
||||
|
||||
- 修改已有插件时保留 `name`、`author`、`pluginType` 和已有兼容字段。
|
||||
- 新插件的 `author` 使用启动提示词中给出的插件作者,不要自行编造作者名;启动提示词未给出作者时先向用户确认。
|
||||
- `fullName` 由 `author/name` 组成,作者变化会导致插件身份变化,不要随意修改。
|
||||
- 只修改需求涉及的字段,避免删除未知的 YAML 字段。
|
||||
- 脚本过长时仍放在同一个 `content` block scalar 中。
|
||||
- 提交前检查 YAML 可解析、`content` 非空、版本和插件类型没有被意外修改。
|
||||
|
||||
@@ -57,4 +57,41 @@ return class DemoAccess extends BaseAccess {
|
||||
- `onTestRequest` 应调用实际 API 方法并在失败时抛出异常。
|
||||
- 对外 API 方法应统一处理分页、错误和返回字段。
|
||||
- 使用 `this.logger` 或框架提供的 logger,禁止 `console.log`。
|
||||
- 一般将API接口方法封装到Access中,其他plugin调用access的方法当做client sdk使用
|
||||
- 一般将API接口方法封装到Access中,其他plugin调用access的方法当做client sdk使用
|
||||
|
||||
## 字段动态显隐
|
||||
|
||||
多种鉴权方式(例如「ApiKey」和「AccessKey签名」)共用一个授权时,
|
||||
用字段上的 `mergeScript` 按所选方式显隐对应字段,只让用户看到当前方式需要的字段:
|
||||
|
||||
```yaml
|
||||
input:
|
||||
authType:
|
||||
title: 鉴权方式
|
||||
value: apikey
|
||||
component:
|
||||
name: a-select
|
||||
vModel: value
|
||||
options:
|
||||
- { label: AccessKey签名, value: aksk }
|
||||
- { label: ApiKey, value: apikey }
|
||||
accessKeyId:
|
||||
title: accessKeyId
|
||||
component:
|
||||
name: a-input
|
||||
vModel: value
|
||||
mergeScript: |2-
|
||||
|
||||
return {
|
||||
show: ctx.compute(({form})=>{
|
||||
return !form.access.authType || form.access.authType === 'aksk';
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
- 判断必须写在 `ctx.compute(({form})=>{ ... })` 回调里;脚本本身在插件定义阶段就拼好了,
|
||||
那时表单还没打开,用参数在服务端判断字段值没有意义。
|
||||
- 授权表单的字段值在 `form.access.xxx`(任务表单才是 `form.xxx`)。
|
||||
- 历史授权没有 `authType` 字段,条件里要用 `!form.access.authType || ...` 兜底走旧逻辑。
|
||||
|
||||
完整用法见父 Skill 的 `references/merge-script.md`。
|
||||
@@ -30,6 +30,8 @@ version: 1.0.0
|
||||
- 指定对应的云平台的 access 类型名称
|
||||
- 设置排序值(可选)
|
||||
- 继承 `AbstractDnsProvider` 类
|
||||
- 插件默认文案使用中文;需要英文时,在注解参数对象中添加同级 `i18n: { "en-US": { ... } }`,不要写成 `metadata.i18n`。`define` 本身就是插件 metadata。
|
||||
- `i18n["en-US"]` 仅配置要翻译的展示字段,如 `title`、`desc`、`input`;输入字段可翻译 `title`、`helper`、组件展示文案和 `optionsMapping`。缺少英文翻译时回退默认中文。
|
||||
|
||||
4. **实现 onInstance 方法**
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ version: 1.0.0
|
||||
- 设置插件分组
|
||||
- 配置默认策略(如 `SkipWhenSucceed`)
|
||||
- 确保类名与插件名称一致
|
||||
- 插件默认文案使用中文;需要英文时,在注解参数对象中添加同级 `i18n: { "en-US": { ... } }`,不要写成 `metadata.i18n`。`define` 本身就是插件 metadata。
|
||||
- `i18n["en-US"]` 仅配置要翻译的展示字段,如 `title`、`desc`、`group`、`input`、`output`;未配置的字段自动回退默认中文。不要翻译插件标识、组件类型、默认值或执行参数。
|
||||
|
||||
3. **定义任务输入参数**
|
||||
|
||||
|
||||
@@ -3,6 +3,29 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* [BUG]使用天翼云CDN部署证书时无法匹配域名 ([bb1f232](https://github.com/certd/certd/commit/bb1f232f415c522851dede979f5d609dda844fd3))
|
||||
* 缺失运行时嵌套依赖时添加清除缓存提示 ([2d0b85b](https://github.com/certd/certd/commit/2d0b85b3054fc1aa82b3ab5db34a2a56308f71f2))
|
||||
* 支持google persist校验方式 ([97d2b50](https://github.com/certd/certd/commit/97d2b5007409ec79ea864d437c473a2f9b5dfae4))
|
||||
* **config:** 修复环境变量加载逻辑并更新配置文件 ([07f0d3b](https://github.com/certd/certd/commit/07f0d3b4d626628a0e3dfc7e5c52e8c4a98bad47))
|
||||
* **ctyun-cdn:** 修复天翼云CDN部署插件的域名选择问题 ([ea7d14c](https://github.com/certd/certd/commit/ea7d14c289b8720781bf101bfef59eac7bb03765))
|
||||
* **webhook:** 修复模版转义换行符,避免手动上传的证书报错 ([2735feb](https://github.com/certd/certd/commit/2735feb3302f8308708dafc8b295adcd4b91d7f0))
|
||||
|
||||
### Features
|
||||
|
||||
* **client:** 新增客户端管理功能 ([3dbbe72](https://github.com/certd/certd/commit/3dbbe72fc15c114ca6b5e8ff45cb21f258b80650))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 宝塔站点列表支持搜索和排序 ([4420472](https://github.com/certd/certd/commit/4420472f8fac272d30fb8ccb1cc2ee9763989001))
|
||||
* 网宿插件双鉴权支持 ([241b2e5](https://github.com/certd/certd/commit/241b2e55848471e61b5d2be0c87a7dc9a0d29557))
|
||||
* **monitor:** 站点证书监控支持手动选中触发检查 ([f60e63f](https://github.com/certd/certd/commit/f60e63fbaf00460d5050cd7705bd75d57dec202d))
|
||||
* **open-api:** openkey增加用途备注 ([bbeaf61](https://github.com/certd/certd/commit/bbeaf617d19750515f6eca51863e74e23bc1de50))
|
||||
* **tencent clb:** 修改所有CLB地域的endpoint为就近接入 ([c427735](https://github.com/certd/certd/commit/c4277350bcc8cf034cf4e76db2a6daa1842bc5d7))
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export default { setSuccess: "Settings saved", editTitle: "Edit Certificate Application Template", addTitle: "Add Certificate Application Template", name: "Template Name", default: "Default", setDefault: "Set as Default", disabled: "Disabled", createTime: "Created At", config: "Configuration" };
|
||||
@@ -3,6 +3,42 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* [BUG]使用天翼云CDN部署证书时无法匹配域名 ([bb1f232](https://github.com/certd/certd/commit/bb1f232f415c522851dede979f5d609dda844fd3))
|
||||
* 缺失运行时嵌套依赖时添加清除缓存提示 ([2d0b85b](https://github.com/certd/certd/commit/2d0b85b3054fc1aa82b3ab5db34a2a56308f71f2))
|
||||
* 支持google persist校验方式 ([97d2b50](https://github.com/certd/certd/commit/97d2b5007409ec79ea864d437c473a2f9b5dfae4))
|
||||
* **config:** 修复环境变量加载逻辑并更新配置文件 ([07f0d3b](https://github.com/certd/certd/commit/07f0d3b4d626628a0e3dfc7e5c52e8c4a98bad47))
|
||||
* **ctyun-cdn:** 修复天翼云CDN部署插件的域名选择问题 ([ea7d14c](https://github.com/certd/certd/commit/ea7d14c289b8720781bf101bfef59eac7bb03765))
|
||||
* **webhook:** 修复模版转义换行符,避免手动上传的证书报错 ([2735feb](https://github.com/certd/certd/commit/2735feb3302f8308708dafc8b295adcd4b91d7f0))
|
||||
|
||||
### Features
|
||||
|
||||
* **client:** 新增客户端管理功能 ([3dbbe72](https://github.com/certd/certd/commit/3dbbe72fc15c114ca6b5e8ff45cb21f258b80650))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 宝塔站点列表支持搜索和排序 ([4420472](https://github.com/certd/certd/commit/4420472f8fac272d30fb8ccb1cc2ee9763989001))
|
||||
* 网宿插件双鉴权支持 ([241b2e5](https://github.com/certd/certd/commit/241b2e55848471e61b5d2be0c87a7dc9a0d29557))
|
||||
* **monitor:** 站点证书监控支持手动选中触发检查 ([f60e63f](https://github.com/certd/certd/commit/f60e63fbaf00460d5050cd7705bd75d57dec202d))
|
||||
* **open-api:** openkey增加用途备注 ([bbeaf61](https://github.com/certd/certd/commit/bbeaf617d19750515f6eca51863e74e23bc1de50))
|
||||
* **tencent clb:** 修改所有CLB地域的endpoint为就近接入 ([c427735](https://github.com/certd/certd/commit/c4277350bcc8cf034cf4e76db2a6daa1842bc5d7))
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复添加步骤会修改所有步骤标题的bug ([51e83e4](https://github.com/certd/certd/commit/51e83e4c38f7f319314fdc38ef33cf5720b2dde0))
|
||||
* 修复证书插件配置无法打开的bug ([5563abb](https://github.com/certd/certd/commit/5563abb13a62140f4dee668ab768cf4ff9371ddb))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 新增余额管理,管理员充值功能 ([bded368](https://github.com/certd/certd/commit/bded368cbb8974b6937ae260e448c25fae5c33ad))
|
||||
* **acme-account-access:** AcmeAccount授权允许修改eab,重新生成account ([6a649aa](https://github.com/certd/certd/commit/6a649aaca083ccd3b517f7d676a58220aa33b37d))
|
||||
* **ui:** 商业版套餐购买不要求设置支付方式 ([e971145](https://github.com/certd/certd/commit/e9711456860d7db40914a0c295534f7bca56f83c))
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
`Certd`默认启用https,监听7002端口
|
||||
如果你想关闭https,或者修改端口,可以在环境变量中配置
|
||||
```shell
|
||||
CERTD_HTTPS_ENABLE=true
|
||||
CERTD_HTTPS_port=7002
|
||||
certd_https_enabled=true
|
||||
certd_https_port=7002
|
||||
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@
|
||||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.44.4"
|
||||
"version": "1.45.0"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/publishlab/node-acme-client/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 支持google persist校验方式 ([97d2b50](https://github.com/publishlab/node-acme-client/commit/97d2b5007409ec79ea864d437c473a2f9b5dfae4))
|
||||
|
||||
## [1.44.4](https://github.com/publishlab/node-acme-client/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Simple and unopinionated ACME client",
|
||||
"private": false,
|
||||
"author": "nmorsman",
|
||||
"version": "1.44.4",
|
||||
"version": "1.45.0",
|
||||
"type": "module",
|
||||
"module": "./dist/index.js",
|
||||
"main": "./dist/index.js",
|
||||
@@ -18,7 +18,7 @@
|
||||
"types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.44.4",
|
||||
"@certd/basic": "^1.45.0",
|
||||
"@peculiar/x509": "^1.11.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"axios": "^1.9.0",
|
||||
@@ -27,6 +27,7 @@
|
||||
"https-proxy-agent": "^7.0.5",
|
||||
"lodash-es": "^4.17.21",
|
||||
"node-forge": "^1.3.1",
|
||||
"psl": "^1.15.0",
|
||||
"punycode.js": "^2.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -76,5 +77,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
"gitHead": "fcbf1045fe3806fa1a0bebf5038a6f67aec283d0"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// @ts-ignore
|
||||
import psl from "psl";
|
||||
|
||||
export function getDnsPersistIssuer(directoryUrl?: string) {
|
||||
if (!directoryUrl) {
|
||||
return "letsencrypt.org";
|
||||
}
|
||||
|
||||
let directory: URL;
|
||||
try {
|
||||
directory = new URL(directoryUrl);
|
||||
} catch {
|
||||
throw new Error(`ACME Directory URL无效,无法生成DNS持久验证Issuer:${directoryUrl}`);
|
||||
}
|
||||
|
||||
const issuer = psl.get(directory.hostname);
|
||||
if (!issuer) {
|
||||
throw new Error(`无法从ACME Directory URL获取可注册主域名:${directory.hostname}`);
|
||||
}
|
||||
return issuer;
|
||||
}
|
||||
@@ -79,3 +79,4 @@ export * from './verify.js'
|
||||
export * from './error.js'
|
||||
|
||||
export * from './util.js'
|
||||
export * from './dns-persist.js'
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **webhook:** 修复模版转义换行符,避免手动上传的证书报错 ([2735feb](https://github.com/certd/certd/commit/2735feb3302f8308708dafc8b295adcd4b91d7f0))
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
@@ -1 +1 @@
|
||||
19:17
|
||||
00:51
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/basic",
|
||||
"private": false,
|
||||
"version": "1.44.4",
|
||||
"version": "1.45.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -54,5 +54,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
"gitHead": "fcbf1045fe3806fa1a0bebf5038a6f67aec283d0"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export const stringUtils = {
|
||||
replaceTemplate(target: string, body: Record<string, unknown>, urlEncode = false) {
|
||||
let bodyStr = target;
|
||||
for (const key of Object.keys(body)) {
|
||||
const rawValue = body[key] == null ? "" : String(body[key]);
|
||||
let value = urlEncode ? encodeURIComponent(rawValue) : rawValue;
|
||||
value = value.replace(/[\u0000-\u001f]/g, char => {
|
||||
const escapes: Record<string, string> = { "\b": "\\b", "\f": "\\f", "\n": "\\n", "\r": "\\r", "\t": "\\t" };
|
||||
return escapes[char] ?? `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`;
|
||||
});
|
||||
bodyStr = bodyStr.replaceAll(`\${${key}}`, value);
|
||||
bodyStr = bodyStr.replaceAll(`{${key}}`, value);
|
||||
}
|
||||
return bodyStr;
|
||||
},
|
||||
|
||||
maxLength(str?: string, length = 100) {
|
||||
if (str) {
|
||||
return str.length > length ? str.slice(0, length) + "..." : str;
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 缺失运行时嵌套依赖时添加清除缓存提示 ([2d0b85b](https://github.com/certd/certd/commit/2d0b85b3054fc1aa82b3ab5db34a2a56308f71f2))
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.44.4",
|
||||
"version": "1.45.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -21,8 +21,8 @@
|
||||
"lint": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.44.4",
|
||||
"@certd/plus-core": "^1.44.4",
|
||||
"@certd/basic": "^1.45.0",
|
||||
"@certd/plus-core": "^1.45.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
"reflect-metadata": "^0.2.2"
|
||||
@@ -51,5 +51,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
"gitHead": "fcbf1045fe3806fa1a0bebf5038a6f67aec283d0"
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ export type AccessInputDefine = FormItemProps & {
|
||||
encrypt?: boolean;
|
||||
};
|
||||
export type AccessDefine = Registrable & {
|
||||
i18n?: Record<string, any>;
|
||||
icon?: string;
|
||||
subtype?: string;
|
||||
dependPlugins?: Record<string, string>;
|
||||
|
||||
@@ -44,6 +44,7 @@ export type NotificationDefine = Registrable & {
|
||||
input?: {
|
||||
[key: string]: NotificationInputDefine;
|
||||
};
|
||||
i18n?: Record<string, any>;
|
||||
};
|
||||
|
||||
export type NotificationInstanceConfig = {
|
||||
|
||||
@@ -43,6 +43,7 @@ export type TaskInputDefine = {
|
||||
} & FormItemProps;
|
||||
|
||||
export type PluginDefine = Registrable & {
|
||||
i18n?: Record<string, any>;
|
||||
default?: any;
|
||||
group?: string;
|
||||
icon?: string;
|
||||
@@ -97,6 +98,7 @@ export type CertTargetItem = {
|
||||
|
||||
export type PipelineEvent<T = any> = {
|
||||
cert: T;
|
||||
certPassword?: string;
|
||||
runnableId: string;
|
||||
pipelineId: number;
|
||||
};
|
||||
|
||||
@@ -64,6 +64,28 @@ describe("RuntimeDepsService", () => {
|
||||
assert.equal(mod.value, 42);
|
||||
});
|
||||
|
||||
it("logs a cache clearing hint when a nested runtime dependency is missing", async () => {
|
||||
const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), "certd-runtime-deps-missing-nested-"));
|
||||
const packageDir = path.join(rootDir, "node_modules", "runtime-only");
|
||||
fs.mkdirSync(packageDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(rootDir, "package.json"), JSON.stringify({ name: "runtime-root", type: "module" }), "utf8");
|
||||
fs.writeFileSync(path.join(packageDir, "package.json"), JSON.stringify({ name: "runtime-only", main: "index.js" }), "utf8");
|
||||
fs.writeFileSync(path.join(packageDir, "index.js"), "module.exports = require('missing-nested');\n", "utf8");
|
||||
const logs: string[] = [];
|
||||
const logger = {
|
||||
info() {},
|
||||
warn() {},
|
||||
error(message: string, ...args: any[]) {
|
||||
logs.push([message, ...args.map(item => item?.message || String(item))].join(" "));
|
||||
},
|
||||
};
|
||||
const service = new RuntimeDepsService({ rootDir }, null);
|
||||
|
||||
await assert.rejects(() => service.importRuntime("runtime-only", logger));
|
||||
assert.ok(logs.some(message => message.includes("Cannot find module 'missing-nested'")));
|
||||
assert.ok(logs.some(message => message.includes("插件管理页面->清除缓存依赖->重启certd")));
|
||||
});
|
||||
|
||||
it("installs configured lazy dependency when import target is missing", async () => {
|
||||
const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), "certd-runtime-deps-lazy-"));
|
||||
const service = new RuntimeDepsService({ rootDir, lazyDependencies: { "lazy-pkg": "^1.2.3" } }, null);
|
||||
|
||||
@@ -251,6 +251,7 @@ export class RuntimeDepsService {
|
||||
}
|
||||
|
||||
let resolved: string;
|
||||
let fromRuntimeDeps = false;
|
||||
try {
|
||||
//尝试加载本项目依赖
|
||||
resolved = this.resolveProjectSpecifier(specifier).resolved;
|
||||
@@ -258,13 +259,22 @@ export class RuntimeDepsService {
|
||||
if (!this.isModuleNotFoundError(error)) {
|
||||
throw error;
|
||||
}
|
||||
fromRuntimeDeps = true;
|
||||
resolved = await this.resolveLazyOrInstallSpecifier(specifier, logger);
|
||||
}
|
||||
if (!resolved) {
|
||||
throw new Error(`依赖未安装成功: ${specifier}`);
|
||||
}
|
||||
|
||||
return await import(pathToFileURL(resolved).href);
|
||||
try {
|
||||
return await import(pathToFileURL(resolved).href);
|
||||
} catch (error: any) {
|
||||
if (fromRuntimeDeps && this.isModuleNotFoundError(error)) {
|
||||
logger.error?.("动态依赖加载失败:", error);
|
||||
logger.error?.("动态依赖加载失败,请前往插件管理页面->清除缓存依赖->重启certd后重试");
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
//动态获取模块解析
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.44.4",
|
||||
"version": "1.45.0",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
@@ -31,5 +31,5 @@
|
||||
"prettier": "3.3.3",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
"gitHead": "fcbf1045fe3806fa1a0bebf5038a6f67aec283d0"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-iframe",
|
||||
"private": false,
|
||||
"version": "1.44.4",
|
||||
"version": "1.45.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -37,5 +37,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
"gitHead": "fcbf1045fe3806fa1a0bebf5038a6f67aec283d0"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/jdcloud",
|
||||
"version": "1.44.4",
|
||||
"version": "1.45.0",
|
||||
"description": "jdcloud openApi sdk",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
@@ -63,5 +63,5 @@
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
"gitHead": "fcbf1045fe3806fa1a0bebf5038a6f67aec283d0"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-k8s",
|
||||
"private": false,
|
||||
"version": "1.44.4",
|
||||
"version": "1.45.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -21,7 +21,7 @@
|
||||
"lint": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.44.4",
|
||||
"@certd/basic": "^1.45.0",
|
||||
"@kubernetes/client-node": "0.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -38,5 +38,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
"gitHead": "fcbf1045fe3806fa1a0bebf5038a6f67aec283d0"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
### Features
|
||||
|
||||
* **client:** 新增客户端管理功能 ([3dbbe72](https://github.com/certd/certd/commit/3dbbe72fc15c114ca6b5e8ff45cb21f258b80650))
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/lib-server",
|
||||
"version": "1.44.4",
|
||||
"version": "1.45.0",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -29,11 +29,11 @@
|
||||
],
|
||||
"license": "AGPL",
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.44.4",
|
||||
"@certd/basic": "^1.44.4",
|
||||
"@certd/pipeline": "^1.44.4",
|
||||
"@certd/plugin-lib": "^1.44.4",
|
||||
"@certd/plus-core": "^1.44.4",
|
||||
"@certd/acme-client": "^1.45.0",
|
||||
"@certd/basic": "^1.45.0",
|
||||
"@certd/pipeline": "^1.45.0",
|
||||
"@certd/plugin-lib": "^1.45.0",
|
||||
"@certd/plus-core": "^1.45.0",
|
||||
"@midwayjs/cache": "3.14.0",
|
||||
"@midwayjs/core": "3.20.11",
|
||||
"@midwayjs/i18n": "3.20.13",
|
||||
@@ -69,5 +69,5 @@
|
||||
"typeorm": "^0.3.20",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
"gitHead": "fcbf1045fe3806fa1a0bebf5038a6f67aec283d0"
|
||||
}
|
||||
|
||||
@@ -174,11 +174,11 @@ export class AccessService extends BaseService<AccessEntity> {
|
||||
throw new ValidateException("userId不能为空");
|
||||
}
|
||||
if (userId !== entity.userId) {
|
||||
throw new PermissionException("您对该Access授权无访问权限");
|
||||
throw new PermissionException(`您对该Access授权${entity.name}(${entity.id})无访问权限`);
|
||||
}
|
||||
}
|
||||
if (projectId != null && projectId !== entity.projectId) {
|
||||
throw new PermissionException("您对该Access授权无访问权限");
|
||||
throw new PermissionException(`您对该Access授权${entity.name}(${entity.id})无访问权限`);
|
||||
}
|
||||
|
||||
// const access = accessRegistry.get(entity.type);
|
||||
|
||||
@@ -26,6 +26,7 @@ export type AddonDefine = Registrable & {
|
||||
};
|
||||
showTest?: boolean;
|
||||
icon?: string;
|
||||
i18n?: Record<string, any>;
|
||||
};
|
||||
|
||||
export type AddonInstanceConfig = {
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/midway-flyway-js",
|
||||
"version": "1.44.4",
|
||||
"version": "1.45.0",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -52,5 +52,5 @@
|
||||
"typeorm": "^0.3.20",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
"gitHead": "fcbf1045fe3806fa1a0bebf5038a6f67aec283d0"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-cert",
|
||||
"private": false,
|
||||
"version": "1.44.4",
|
||||
"version": "1.45.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -20,7 +20,7 @@
|
||||
"lint": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/plugin-lib": "^1.44.4"
|
||||
"@certd/plugin-lib": "^1.45.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.3.12",
|
||||
@@ -38,5 +38,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
"gitHead": "fcbf1045fe3806fa1a0bebf5038a6f67aec283d0"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-lib",
|
||||
"private": false,
|
||||
"version": "1.44.4",
|
||||
"version": "1.45.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -17,9 +17,9 @@
|
||||
"lint": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.44.4",
|
||||
"@certd/basic": "^1.44.4",
|
||||
"@certd/pipeline": "^1.44.4",
|
||||
"@certd/acme-client": "^1.45.0",
|
||||
"@certd/basic": "^1.45.0",
|
||||
"@certd/pipeline": "^1.45.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"jszip": "^3.10.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
@@ -45,5 +45,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
"gitHead": "fcbf1045fe3806fa1a0bebf5038a6f67aec283d0"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { IAccess, IAccessService, IServiceGetter, PageRes, PageSearch, Registrab
|
||||
|
||||
export type DnsProviderDefine = Registrable & {
|
||||
accessType: string;
|
||||
i18n?: Record<string, any>;
|
||||
icon?: string;
|
||||
dependPlugins?: Record<string, string>;
|
||||
dependPackages?: Record<string, string>;
|
||||
|
||||
@@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.45.0](https://github.com/certd/certd/compare/v1.44.4...v1.45.0) (2026-10-02)
|
||||
|
||||
### Features
|
||||
|
||||
* **client:** 新增客户端管理功能 ([3dbbe72](https://github.com/certd/certd/commit/3dbbe72fc15c114ca6b5e8ff45cb21f258b80650))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **monitor:** 站点证书监控支持手动选中触发检查 ([f60e63f](https://github.com/certd/certd/commit/f60e63fbaf00460d5050cd7705bd75d57dec202d))
|
||||
* **open-api:** openkey增加用途备注 ([bbeaf61](https://github.com/certd/certd/commit/bbeaf617d19750515f6eca51863e74e23bc1de50))
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -13,7 +13,7 @@ const { packages } = getPackagesSync(process.cwd());
|
||||
|
||||
const tailwindPackages = [];
|
||||
|
||||
packages.forEach((pkg) => {
|
||||
packages.forEach(pkg => {
|
||||
// apps目录下和 @vben-core/tailwind-ui 包需要使用到 tailwindcss ui
|
||||
// if (fs.existsSync(path.join(pkg.dir, 'tailwind.config.mjs'))) {
|
||||
tailwindPackages.push(pkg.dir);
|
||||
@@ -25,96 +25,96 @@ const shadcnUiColors = {
|
||||
DEFAULT: "hsl(var(--accent))",
|
||||
foreground: "hsl(var(--accent-foreground))",
|
||||
hover: "hsl(var(--accent-hover))",
|
||||
lighter: "has(val(--accent-lighter))"
|
||||
lighter: "has(val(--accent-lighter))",
|
||||
},
|
||||
background: {
|
||||
deep: "hsl(var(--background-deep))",
|
||||
DEFAULT: "hsl(var(--background))"
|
||||
DEFAULT: "hsl(var(--background))",
|
||||
},
|
||||
border: {
|
||||
DEFAULT: "hsl(var(--border))"
|
||||
DEFAULT: "hsl(var(--border))",
|
||||
},
|
||||
card: {
|
||||
DEFAULT: "hsl(var(--card))",
|
||||
foreground: "hsl(var(--card-foreground))"
|
||||
foreground: "hsl(var(--card-foreground))",
|
||||
},
|
||||
destructive: {
|
||||
...createColorsPalette("destructive"),
|
||||
DEFAULT: "hsl(var(--destructive))"
|
||||
DEFAULT: "hsl(var(--destructive))",
|
||||
},
|
||||
|
||||
foreground: {
|
||||
DEFAULT: "hsl(var(--foreground))"
|
||||
DEFAULT: "hsl(var(--foreground))",
|
||||
},
|
||||
|
||||
input: {
|
||||
background: "hsl(var(--input-background))",
|
||||
DEFAULT: "hsl(var(--input))"
|
||||
DEFAULT: "hsl(var(--input))",
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: "hsl(var(--muted))",
|
||||
foreground: "hsl(var(--muted-foreground))"
|
||||
foreground: "hsl(var(--muted-foreground))",
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: "hsl(var(--popover))",
|
||||
foreground: "hsl(var(--popover-foreground))"
|
||||
foreground: "hsl(var(--popover-foreground))",
|
||||
},
|
||||
primary: {
|
||||
...createColorsPalette("primary"),
|
||||
DEFAULT: "hsl(var(--primary))"
|
||||
DEFAULT: "hsl(var(--primary))",
|
||||
},
|
||||
|
||||
ring: "hsl(var(--ring))",
|
||||
secondary: {
|
||||
DEFAULT: "hsl(var(--secondary))",
|
||||
desc: "hsl(var(--secondary-desc))",
|
||||
foreground: "hsl(var(--secondary-foreground))"
|
||||
}
|
||||
foreground: "hsl(var(--secondary-foreground))",
|
||||
},
|
||||
};
|
||||
|
||||
const customColors = {
|
||||
green: {
|
||||
...createColorsPalette("green"),
|
||||
foreground: "hsl(var(--success-foreground))"
|
||||
foreground: "hsl(var(--success-foreground))",
|
||||
},
|
||||
header: {
|
||||
DEFAULT: "hsl(var(--header))"
|
||||
DEFAULT: "hsl(var(--header))",
|
||||
},
|
||||
heavy: {
|
||||
DEFAULT: "hsl(var(--heavy))",
|
||||
foreground: "hsl(var(--heavy-foreground))"
|
||||
foreground: "hsl(var(--heavy-foreground))",
|
||||
},
|
||||
main: {
|
||||
DEFAULT: "hsl(var(--main))"
|
||||
DEFAULT: "hsl(var(--main))",
|
||||
},
|
||||
overlay: {
|
||||
content: "hsl(var(--overlay-content))",
|
||||
DEFAULT: "hsl(var(--overlay))"
|
||||
DEFAULT: "hsl(var(--overlay))",
|
||||
},
|
||||
red: {
|
||||
...createColorsPalette("red"),
|
||||
foreground: "hsl(var(--destructive-foreground))"
|
||||
foreground: "hsl(var(--destructive-foreground))",
|
||||
},
|
||||
sidebar: {
|
||||
deep: "hsl(var(--sidebar-deep))",
|
||||
DEFAULT: "hsl(var(--sidebar))"
|
||||
DEFAULT: "hsl(var(--sidebar))",
|
||||
},
|
||||
success: {
|
||||
...createColorsPalette("success"),
|
||||
DEFAULT: "hsl(var(--success))"
|
||||
DEFAULT: "hsl(var(--success))",
|
||||
},
|
||||
warning: {
|
||||
...createColorsPalette("warning"),
|
||||
DEFAULT: "hsl(var(--warning))"
|
||||
DEFAULT: "hsl(var(--warning))",
|
||||
},
|
||||
yellow: {
|
||||
...createColorsPalette("yellow"),
|
||||
foreground: "hsl(var(--warning-foreground))"
|
||||
}
|
||||
foreground: "hsl(var(--warning-foreground))",
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
content: ["./index.html", ...tailwindPackages.map((item) => path.join(item, "src/**/*.{vue,js,ts,jsx,tsx,svelte,astro,html}"))],
|
||||
content: ["./index.html", ...tailwindPackages.map(item => path.join(item, "src/**/*.{vue,js,ts,jsx,tsx,svelte,astro,html}"))],
|
||||
darkMode: "selector",
|
||||
plugins: [animate, typographyPlugin, addDynamicIconSelectors(), enterAnimationPlugin],
|
||||
prefix: "",
|
||||
@@ -123,8 +123,8 @@ export default {
|
||||
center: true,
|
||||
padding: "2rem",
|
||||
screens: {
|
||||
"2xl": "1400px"
|
||||
}
|
||||
"2xl": "1400px",
|
||||
},
|
||||
},
|
||||
extend: {
|
||||
animation: {
|
||||
@@ -132,64 +132,67 @@ export default {
|
||||
"accordion-up": "accordion-up 0.2s ease-out",
|
||||
"collapsible-down": "collapsible-down 0.2s ease-in-out",
|
||||
"collapsible-up": "collapsible-up 0.2s ease-in-out",
|
||||
float: "float 5s linear 0ms infinite"
|
||||
float: "float 5s linear 0ms infinite",
|
||||
},
|
||||
flex: {
|
||||
2: "2 1 0%",
|
||||
},
|
||||
|
||||
animationDuration: {
|
||||
2000: "2000ms",
|
||||
3000: "3000ms"
|
||||
3000: "3000ms",
|
||||
},
|
||||
borderRadius: {
|
||||
lg: "var(--radius)",
|
||||
md: "calc(var(--radius) - 2px)",
|
||||
sm: "calc(var(--radius) - 4px)",
|
||||
xl: "calc(var(--radius) + 4px)"
|
||||
xl: "calc(var(--radius) + 4px)",
|
||||
},
|
||||
boxShadow: {
|
||||
float: `0 6px 16px 0 rgb(0 0 0 / 8%),
|
||||
0 3px 6px -4px rgb(0 0 0 / 12%),
|
||||
0 9px 28px 8px rgb(0 0 0 / 5%)`
|
||||
0 9px 28px 8px rgb(0 0 0 / 5%)`,
|
||||
},
|
||||
colors: {
|
||||
...customColors,
|
||||
...shadcnUiColors
|
||||
...shadcnUiColors,
|
||||
},
|
||||
fontFamily: {
|
||||
sans: [
|
||||
"var(--font-family)"
|
||||
"var(--font-family)",
|
||||
// ...defaultTheme.fontFamily.sans
|
||||
]
|
||||
],
|
||||
},
|
||||
keyframes: {
|
||||
"accordion-down": {
|
||||
from: { height: "0" },
|
||||
to: { height: "var(--radix-accordion-content-height)" }
|
||||
to: { height: "var(--radix-accordion-content-height)" },
|
||||
},
|
||||
"accordion-up": {
|
||||
from: { height: "var(--radix-accordion-content-height)" },
|
||||
to: { height: "0" }
|
||||
to: { height: "0" },
|
||||
},
|
||||
"collapsible-down": {
|
||||
from: { height: "0" },
|
||||
to: { height: "var(--radix-collapsible-content-height)" }
|
||||
to: { height: "var(--radix-collapsible-content-height)" },
|
||||
},
|
||||
"collapsible-up": {
|
||||
from: { height: "var(--radix-collapsible-content-height)" },
|
||||
to: { height: "0" }
|
||||
to: { height: "0" },
|
||||
},
|
||||
float: {
|
||||
"0%": { transform: "translateY(0)" },
|
||||
"50%": { transform: "translateY(-20px)" },
|
||||
"100%": { transform: "translateY(0)" }
|
||||
}
|
||||
"100%": { transform: "translateY(0)" },
|
||||
},
|
||||
},
|
||||
zIndex: {
|
||||
100: "100",
|
||||
1000: "1000"
|
||||
}
|
||||
}
|
||||
1000: "1000",
|
||||
},
|
||||
},
|
||||
},
|
||||
safelist: ["dark"]
|
||||
safelist: ["dark"],
|
||||
};
|
||||
|
||||
function createColorsPalette(name) {
|
||||
@@ -249,6 +252,6 @@ function createColorsPalette(name) {
|
||||
// 主色文本激活态
|
||||
"text-active": `hsl(var(--${name}-700))`,
|
||||
// 主色文本悬浮态
|
||||
"text-hover": `hsl(var(--${name}-600))`
|
||||
"text-hover": `hsl(var(--${name}-600))`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,6 +10,6 @@ export default {
|
||||
"postcss-import": {},
|
||||
"postcss-preset-env": {},
|
||||
tailwindcss: { config },
|
||||
"tailwindcss/nesting": {}
|
||||
}
|
||||
"tailwindcss/nesting": {},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-client",
|
||||
"version": "1.44.4",
|
||||
"version": "1.45.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
@@ -34,11 +34,11 @@
|
||||
"@aws-sdk/s3-request-presigner": "^3.964.0",
|
||||
"@certd/vue-js-cron-light": "^4.0.14",
|
||||
"@ctrl/tinycolor": "^4.1.0",
|
||||
"@fast-crud/editor-code": "^1.28.7",
|
||||
"@fast-crud/fast-crud": "^1.28.7",
|
||||
"@fast-crud/fast-extends": "^1.28.7",
|
||||
"@fast-crud/ui-antdv4": "^1.28.7",
|
||||
"@fast-crud/ui-interface": "^1.28.7",
|
||||
"@fast-crud/editor-code": "^1.29.0",
|
||||
"@fast-crud/fast-crud": "^1.29.0",
|
||||
"@fast-crud/fast-extends": "^1.29.0",
|
||||
"@fast-crud/ui-antdv4": "^1.29.0",
|
||||
"@fast-crud/ui-interface": "^1.29.0",
|
||||
"@iconify/tailwind": "^1.2.0",
|
||||
"@iconify/vue": "^4.1.1",
|
||||
"@manypkg/get-packages": "^2.2.2",
|
||||
@@ -104,8 +104,8 @@
|
||||
"zod-defaults": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/lib-iframe": "^1.44.4",
|
||||
"@certd/pipeline": "^1.44.4",
|
||||
"@certd/lib-iframe": "^1.45.0",
|
||||
"@certd/pipeline": "^1.45.0",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.12",
|
||||
|
||||
@@ -4,6 +4,7 @@ import { errorLog, errorCreate } from "./tools";
|
||||
import { env } from "/src/utils/util.env";
|
||||
import { useUserStore } from "/@/store/user";
|
||||
import { useProjectStore } from "../store/project";
|
||||
import { i18n } from "/@/locales";
|
||||
|
||||
export class CodeError extends Error {
|
||||
code: number;
|
||||
@@ -139,6 +140,7 @@ function createRequestFunction(service: any) {
|
||||
const configDefault: any = {
|
||||
headers: {
|
||||
"Content-Type": get(config, "headers.Content-Type", "application/json"),
|
||||
"Accept-Language": i18n.global.locale.value,
|
||||
} as any,
|
||||
timeout: 30000,
|
||||
baseURL: env.API,
|
||||
@@ -154,6 +156,10 @@ function createRequestFunction(service: any) {
|
||||
configDefault.headers.Authorization = token;
|
||||
}
|
||||
Object.assign(configDefault, config);
|
||||
configDefault.headers = {
|
||||
...configDefault.headers,
|
||||
"Accept-Language": i18n.global.locale.value,
|
||||
};
|
||||
|
||||
if (!configDefault.params.projectId && projectStore.isEnterprise && !config.url.startsWith("/sys") && !config.url.startsWith("http")) {
|
||||
configDefault.params.projectId = projectStore.currentProject?.id;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="flex captcha-image-input">
|
||||
<a-input :value="valueRef" :placeholder="t('certd.captcha.inputImageCode')" autocomplete="off" @update:value="onChange">
|
||||
<a-input :value="valueRef" :placeholder="t('certd.common.captcha.inputImageCode')" autocomplete="off" @update:value="onChange">
|
||||
<template #prefix>
|
||||
<fs-icon icon="ion:image-outline"></fs-icon>
|
||||
</template>
|
||||
</a-input>
|
||||
<div class="input-right pointer" :title="t('certd.captcha.refresh')">
|
||||
<div class="input-right pointer" :title="t('certd.common.captcha.refresh')">
|
||||
<img class="image-code" :src="imageCodeSrc" @click="resetImageCode" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<div class="sweep-animation"></div>
|
||||
<div class="box-content">
|
||||
<div class="box-icon">✓</div>
|
||||
<span v-if="modelValue == null" class="status-text">{{ t("certd.captcha.clickToVerify") }}</span>
|
||||
<span v-else class="status-text">{{ t("certd.captcha.verifySuccess") }}</span>
|
||||
<span v-if="modelValue == null" class="status-text">{{ t("certd.common.captcha.clickToVerify") }}</span>
|
||||
<span v-else class="status-text">{{ t("certd.common.captcha.verifySuccess") }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,7 +58,7 @@ function callback(res: { ret: number; ticket: string; randstr: string; errorCode
|
||||
|
||||
if (res.errorCode && res.errorCode > 0) {
|
||||
notification.error({
|
||||
message: t("certd.captcha.verifyFailed", { message: res.errorMessage || res.errorCode }),
|
||||
message: t("certd.common.captcha.verifyFailed", { message: res.errorMessage || res.errorCode }),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -85,13 +85,13 @@ function loadErrorCallback(error: any) {
|
||||
// errorMessage: "jsload_error",
|
||||
// });
|
||||
notification.error({
|
||||
message: t("certd.captcha.loadFailed", { message: error?.message || error }),
|
||||
message: t("certd.common.captcha.loadFailed", { message: error?.message || error }),
|
||||
});
|
||||
}
|
||||
async function triggerCaptcha() {
|
||||
if (!loaded.value) {
|
||||
notification.error({
|
||||
message: t("certd.captcha.notLoaded"),
|
||||
message: t("certd.common.captcha.notLoaded"),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
+7
-5
@@ -5,6 +5,7 @@
|
||||
<script lang="ts">
|
||||
import { ref } from "vue";
|
||||
import * as api from "./api";
|
||||
import { resolvePluginLocale } from "/@/store/plugin";
|
||||
|
||||
export default {
|
||||
name: "DnsProviderSelector",
|
||||
@@ -21,12 +22,13 @@ export default {
|
||||
async function onCreate() {
|
||||
const list = await api.GetList();
|
||||
const array: any[] = [];
|
||||
for (let item of list) {
|
||||
for (const item of list) {
|
||||
const localizedItem = resolvePluginLocale(item);
|
||||
array.push({
|
||||
value: item.name,
|
||||
label: item.title,
|
||||
icon: item.icon,
|
||||
accessType: item.accessType,
|
||||
value: localizedItem.name,
|
||||
label: localizedItem.title,
|
||||
icon: localizedItem.icon,
|
||||
accessType: localizedItem.accessType,
|
||||
});
|
||||
}
|
||||
options.value = array;
|
||||
|
||||
+11
-11
@@ -4,7 +4,7 @@
|
||||
<!-- <td class="domain">-->
|
||||
<!-- {{ props.domain }}-->
|
||||
<!-- </td>-->
|
||||
<td class="host-record" :title="t('certd.verifyPlan.domainTitle', { domain: props.domain })">
|
||||
<td class="host-record" :title="t('certd.certdomain.verifyPlan.domainTitle', { domain: props.domain })">
|
||||
<fs-copyable v-model="cnameRecord.hostRecord"></fs-copyable>
|
||||
</td>
|
||||
<td style="text-align: center">CNAME</td>
|
||||
@@ -17,18 +17,18 @@
|
||||
<a-tooltip v-if="cnameRecord.error" :title="cnameRecord.error">
|
||||
<fs-icon class="ml-5 color-red" icon="ion:warning-outline"></fs-icon>
|
||||
</a-tooltip>
|
||||
<a-tooltip v-if="cnameRecord.status === 'valid'" :title="t('certd.verifyPlan.resetStatusTooltip')">
|
||||
<a-tooltip v-if="cnameRecord.status === 'valid'" :title="t('certd.certdomain.verifyPlan.resetStatusTooltip')">
|
||||
<fs-icon class="ml-2 color-yellow text-md pointer" icon="solar:undo-left-square-bold" @click="resetStatus"></fs-icon>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</td>
|
||||
<td class="center">
|
||||
<template v-if="cnameRecord.status !== 'valid'">
|
||||
<a-button type="primary" size="small" :loading="loading" @click="doVerify">{{ t("certd.verifyPlan.clickToValidate") }}</a-button>
|
||||
<a-button type="primary" size="small" :loading="loading" @click="doVerify">{{ t("certd.certdomain.verifyPlan.clickToValidate") }}</a-button>
|
||||
<cname-tip :record="cnameRecord"></cname-tip>
|
||||
</template>
|
||||
|
||||
<div v-else class="helper" :title="t('certd.verifyPlan.keepCnameTitle')">{{ t("certd.verifyPlan.keepCname") }}</div>
|
||||
<div v-else class="helper" :title="t('certd.certdomain.verifyPlan.keepCnameTitle')">{{ t("certd.certdomain.verifyPlan.keepCname") }}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -46,11 +46,11 @@ import { utils } from "/@/utils/index.js";
|
||||
const { t } = useI18n();
|
||||
const statusDict = dict({
|
||||
data: [
|
||||
{ label: t("certd.verifyPlan.status.pendingCname"), value: "cname", color: "warning" },
|
||||
{ label: t("certd.verifyPlan.status.validating"), value: "validating", color: "blue" },
|
||||
{ label: t("certd.verifyPlan.status.valid"), value: "valid", color: "green" },
|
||||
{ label: t("certd.verifyPlan.status.failed"), value: "failed", color: "red" },
|
||||
{ label: t("certd.verifyPlan.status.timeout"), value: "timeout", color: "red" },
|
||||
{ label: t("certd.certdomain.verifyPlan.status.pendingCname"), value: "cname", color: "warning" },
|
||||
{ label: t("certd.certdomain.verifyPlan.status.validating"), value: "validating", color: "blue" },
|
||||
{ label: t("certd.certdomain.verifyPlan.status.valid"), value: "valid", color: "green" },
|
||||
{ label: t("certd.certdomain.verifyPlan.status.failed"), value: "failed", color: "red" },
|
||||
{ label: t("certd.certdomain.verifyPlan.status.timeout"), value: "timeout", color: "red" },
|
||||
],
|
||||
});
|
||||
|
||||
@@ -129,8 +129,8 @@ async function doVerify() {
|
||||
|
||||
async function resetStatus() {
|
||||
Modal.confirm({
|
||||
title: t("certd.verifyPlan.resetStatus"),
|
||||
content: t("certd.verifyPlan.confirmResetStatus"),
|
||||
title: t("certd.certdomain.verifyPlan.resetStatus"),
|
||||
content: t("certd.certdomain.verifyPlan.confirmResetStatus"),
|
||||
onOk: async () => {
|
||||
await api.ResetStatus(cnameRecord.value.id);
|
||||
await loadRecord();
|
||||
|
||||
+7
-7
@@ -2,17 +2,17 @@
|
||||
<a-tooltip :overlay-style="{ maxWidth: '400px' }">
|
||||
<template #title>
|
||||
<div>
|
||||
<div>{{ t("certd.verifyPlan.cnameTip.intro") }}</div>
|
||||
<div>{{ t("certd.verifyPlan.cnameTip.step1", { domain: record.domain }) }}</div>
|
||||
<div>{{ t("certd.verifyPlan.cnameTip.step2") }}</div>
|
||||
<div>{{ t("certd.verifyPlan.cnameTip.step3", { value: record.recordValue }) }}</div>
|
||||
<div>{{ t("certd.certdomain.verifyPlan.cnameTip.intro") }}</div>
|
||||
<div>{{ t("certd.certdomain.verifyPlan.cnameTip.step1", { domain: record.domain }) }}</div>
|
||||
<div>{{ t("certd.certdomain.verifyPlan.cnameTip.step2") }}</div>
|
||||
<div>{{ t("certd.certdomain.verifyPlan.cnameTip.step3", { value: record.recordValue }) }}</div>
|
||||
<div>
|
||||
{{ t("certd.verifyPlan.cnameTip.step4") }}
|
||||
{{ t("certd.certdomain.verifyPlan.cnameTip.step4") }}
|
||||
<fs-copyable :style="{ color: '#52c41a' }" :model-value="nslookupCmd"></fs-copyable>
|
||||
{{ t("certd.verifyPlan.cnameTip.or") }}
|
||||
{{ t("certd.certdomain.verifyPlan.cnameTip.or") }}
|
||||
<fs-copyable :style="{ color: '#52c41a' }" :model-value="digCmd"></fs-copyable>
|
||||
</div>
|
||||
<div>{{ t("certd.verifyPlan.cnameTip.step5") }}</div>
|
||||
<div>{{ t("certd.certdomain.verifyPlan.cnameTip.step5") }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<fs-icon class="ml-5 pointer" icon="mingcute:question-line"></fs-icon>
|
||||
|
||||
+5
-5
@@ -2,11 +2,11 @@
|
||||
<table class="cname-verify-plan">
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="col-host">{{ t("certd.verifyPlan.hostRecord") }}</td>
|
||||
<td class="col-type center">{{ t("certd.verifyPlan.recordType") }}</td>
|
||||
<td class="col-value">{{ t("certd.verifyPlan.setCnameRecord") }}</td>
|
||||
<td class="col-status center">{{ t("certd.status") }}</td>
|
||||
<td class="col-action center">{{ t("certd.verifyPlan.operation") }}</td>
|
||||
<td class="col-host">{{ t("certd.certdomain.verifyPlan.hostRecord") }}</td>
|
||||
<td class="col-type center">{{ t("certd.certdomain.verifyPlan.recordType") }}</td>
|
||||
<td class="col-value">{{ t("certd.certdomain.verifyPlan.setCnameRecord") }}</td>
|
||||
<td class="col-status center">{{ t("certd.common.status") }}</td>
|
||||
<td class="col-action center">{{ t("certd.certdomain.verifyPlan.operation") }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<template v-for="key in domains" :key="key">
|
||||
|
||||
+5
-5
@@ -2,10 +2,10 @@
|
||||
<table class="http-verify-plan">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width: 160px">{{ t("certd.verifyPlan.websiteDomain") }}</td>
|
||||
<td style="width: 100px; text-align: center">{{ t("certd.verifyPlan.uploadMethod") }}</td>
|
||||
<td style="width: 150px">{{ t("certd.verifyPlan.uploadAccess") }}</td>
|
||||
<td style="width: 200px">{{ t("certd.verifyPlan.websiteRootPath") }}</td>
|
||||
<td style="width: 160px">{{ t("certd.certdomain.verifyPlan.websiteDomain") }}</td>
|
||||
<td style="width: 100px; text-align: center">{{ t("certd.certdomain.verifyPlan.uploadMethod") }}</td>
|
||||
<td style="width: 150px">{{ t("certd.certdomain.verifyPlan.uploadAccess") }}</td>
|
||||
<td style="width: 200px">{{ t("certd.certdomain.verifyPlan.websiteRootPath") }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-if="records" class="http-record-body">
|
||||
@@ -21,7 +21,7 @@
|
||||
<access-selector v-model="item.httpUploaderAccess" :type="item.httpUploaderType" @change="onRecordChange"></access-selector>
|
||||
</td>
|
||||
<td>
|
||||
<a-input v-model:value="item.httpUploadRootDir" :placeholder="t('certd.verifyPlan.websiteRootPlaceholder')" @change="onRecordChange"></a-input>
|
||||
<a-input v-model:value="item.httpUploadRootDir" :placeholder="t('certd.certdomain.verifyPlan.websiteRootPlaceholder')" @change="onRecordChange"></a-input>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
+12
-12
@@ -5,7 +5,7 @@
|
||||
<div class="plan-box bg-white dark:bg-neutral-700">
|
||||
<div class="fullscreen-button pointer flex-center" @click="fullscreen = !fullscreen">
|
||||
<span v-if="!fullscreen" style="font-size: 10px" class="flex-center">
|
||||
{{ t("certd.verifyPlan.expandTip") }}
|
||||
{{ t("certd.certdomain.verifyPlan.expandTip") }}
|
||||
<fs-icon icon="ion:arrow-forward-outline"></fs-icon>
|
||||
</span>
|
||||
<fs-icon :icon="fullscreen ? 'material-symbols:fullscreen-exit' : 'material-symbols:fullscreen'"></fs-icon>
|
||||
@@ -13,9 +13,9 @@
|
||||
<table class="plan-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="min-width: 100px">{{ t("certd.verifyPlan.mainDomain") }}</th>
|
||||
<th>{{ t("certd.verifyPlan.challengeType") }}</th>
|
||||
<th>{{ t("certd.verifyPlan.challengePlan") }}</th>
|
||||
<th style="min-width: 100px">{{ t("certd.certdomain.verifyPlan.mainDomain") }}</th>
|
||||
<th>{{ t("certd.certdomain.verifyPlan.challengeType") }}</th>
|
||||
<th>{{ t("certd.certdomain.verifyPlan.challengePlan") }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -30,13 +30,13 @@
|
||||
<div class="plan">
|
||||
<div v-if="item.type === 'dns'" class="plan-dns">
|
||||
<div class="form-item">
|
||||
<span class="label">{{ t("certd.verifyPlan.dnsType") }}:</span>
|
||||
<span class="label">{{ t("certd.certdomain.verifyPlan.dnsType") }}:</span>
|
||||
<span class="input">
|
||||
<fs-dict-select
|
||||
v-model:value="item.dnsProviderType"
|
||||
size="small"
|
||||
:dict="dnsProviderTypeDict"
|
||||
:placeholder="t('certd.verifyPlan.dnsProvider')"
|
||||
:placeholder="t('certd.certdomain.verifyPlan.dnsProvider')"
|
||||
@change="onPlanChanged"
|
||||
@selected-change="onDnsProviderChange(item, $event)"
|
||||
></fs-dict-select>
|
||||
@@ -44,13 +44,13 @@
|
||||
</div>
|
||||
<a-divider type="vertical" />
|
||||
<div class="form-item">
|
||||
<span class="label">{{ t("certd.verifyPlan.dnsAccess") }}:</span>
|
||||
<span class="label">{{ t("certd.certdomain.verifyPlan.dnsAccess") }}:</span>
|
||||
<span class="input">
|
||||
<access-selector
|
||||
v-model="item.dnsProviderAccessId"
|
||||
size="small"
|
||||
:type="item.dnsProviderAccessType || item.dnsProviderType"
|
||||
:placeholder="t('certd.verifyPlan.pleaseSelect')"
|
||||
:placeholder="t('certd.certdomain.verifyPlan.pleaseSelect')"
|
||||
@change="onPlanChanged"
|
||||
></access-selector>
|
||||
</span>
|
||||
@@ -70,7 +70,7 @@
|
||||
</div>
|
||||
<div v-if="item.type === 'http'" class="plan-http">
|
||||
<http-verify-plan v-model="item.httpVerifyPlan" @change="onPlanChanged" />
|
||||
<div class="helper">{{ t("certd.verifyPlan.httpHelper") }}</div>
|
||||
<div class="helper">{{ t("certd.certdomain.verifyPlan.httpHelper") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
@@ -105,7 +105,7 @@ const { t } = useI18n();
|
||||
|
||||
const challengeTypeOptions = ref<any[]>([
|
||||
{
|
||||
label: t("certd.verifyPlan.dnsChallenge"),
|
||||
label: t("certd.certdomain.verifyPlan.dnsChallenge"),
|
||||
value: "dns",
|
||||
},
|
||||
{
|
||||
@@ -113,11 +113,11 @@ const challengeTypeOptions = ref<any[]>([
|
||||
value: "dns-persist",
|
||||
},
|
||||
{
|
||||
label: t("certd.verifyPlan.cnameChallenge"),
|
||||
label: t("certd.certdomain.verifyPlan.cnameChallenge"),
|
||||
value: "cname",
|
||||
},
|
||||
{
|
||||
label: t("certd.verifyPlan.httpChallenge"),
|
||||
label: t("certd.certdomain.verifyPlan.httpChallenge"),
|
||||
value: "http",
|
||||
},
|
||||
]);
|
||||
|
||||
+6
-6
@@ -14,7 +14,7 @@ function checkDomainVerifyPlan(rule: any, value: DomainsVerifyPlanInput) {
|
||||
for (const subDomain of subDomains) {
|
||||
const plan = value[domain].cnameVerifyPlan[subDomain];
|
||||
if (plan.status !== "valid") {
|
||||
throw new Error($t("certd.verifyPlan.errors.cnameNotValid", { domain: subDomain }));
|
||||
throw new Error($t("certd.certdomain.verifyPlan.errors.cnameNotValid", { domain: subDomain }));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ function checkDomainVerifyPlan(rule: any, value: DomainsVerifyPlanInput) {
|
||||
for (const item of domains) {
|
||||
//如果有通配符域名则不允许使用http校验
|
||||
if (item.startsWith("*.")) {
|
||||
throw new Error($t("certd.verifyPlan.errors.wildcardNotSupportHttp", { domain: item }));
|
||||
throw new Error($t("certd.certdomain.verifyPlan.errors.wildcardNotSupportHttp", { domain: item }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,19 +32,19 @@ function checkDomainVerifyPlan(rule: any, value: DomainsVerifyPlanInput) {
|
||||
for (const subDomain of subDomains) {
|
||||
const plan = value[domain].httpVerifyPlan[subDomain];
|
||||
if (!plan.httpUploaderType) {
|
||||
throw new Error($t("certd.verifyPlan.errors.uploadMethodRequired", { domain: subDomain }));
|
||||
throw new Error($t("certd.certdomain.verifyPlan.errors.uploadMethodRequired", { domain: subDomain }));
|
||||
}
|
||||
if (!plan.httpUploaderAccess) {
|
||||
throw new Error($t("certd.verifyPlan.errors.uploadAccessRequired", { domain: subDomain }));
|
||||
throw new Error($t("certd.certdomain.verifyPlan.errors.uploadAccessRequired", { domain: subDomain }));
|
||||
}
|
||||
if (!plan.httpUploadRootDir) {
|
||||
throw new Error($t("certd.verifyPlan.errors.websiteRootRequired", { domain: subDomain }));
|
||||
throw new Error($t("certd.certdomain.verifyPlan.errors.websiteRootRequired", { domain: subDomain }));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (type === "dns") {
|
||||
if (!value[domain].dnsProviderType || !value[domain].dnsProviderAccessId) {
|
||||
throw new Error($t("certd.verifyPlan.errors.dnsProviderRequired", { domain }));
|
||||
throw new Error($t("certd.certdomain.verifyPlan.errors.dnsProviderRequired", { domain }));
|
||||
}
|
||||
} else if (type === "dns-persist") {
|
||||
const subDomains = Object.keys(value[domain].dnsPersistVerifyPlan || {});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="api-test">
|
||||
<div>
|
||||
<fs-button :loading="loading" type="primary" :text="t('certd.pluginCommon.test')" icon="ion:refresh-outline" @click="doTest"></fs-button>
|
||||
<fs-button :loading="loading" type="primary" :text="t('certd.common.pluginCommon.test')" icon="ion:refresh-outline" @click="doTest"></fs-button>
|
||||
</div>
|
||||
|
||||
<div class="helper" :class="{ error: hasError }">
|
||||
@@ -64,14 +64,14 @@ const doTest = async () => {
|
||||
{
|
||||
onError(err: any) {
|
||||
hasError.value = true;
|
||||
message.value = t("certd.pluginCommon.errorWithMessage", { message: err.message });
|
||||
message.value = t("certd.common.pluginCommon.errorWithMessage", { message: err.message });
|
||||
},
|
||||
showErrorNotify: false,
|
||||
}
|
||||
);
|
||||
message.value = t("certd.pluginCommon.testRequestSuccess");
|
||||
message.value = t("certd.common.pluginCommon.testRequestSuccess");
|
||||
if (res) {
|
||||
message.value += t("certd.pluginCommon.responseSuffix", { response: JSON.stringify(res) });
|
||||
message.value += t("certd.common.pluginCommon.responseSuffix", { response: JSON.stringify(res) });
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
|
||||
@@ -42,7 +42,7 @@ function findStepFromPipeline(targetStepId: string) {
|
||||
const errorRef = ref("");
|
||||
function getStepIdFromInputKey(inputKey: string) {
|
||||
if (!inputKey) {
|
||||
errorRef.value = t("certd.pluginCommon.selectCertFirst");
|
||||
errorRef.value = t("certd.common.pluginCommon.selectCertFirst");
|
||||
return;
|
||||
}
|
||||
return inputKey.split(".")[1];
|
||||
@@ -51,7 +51,7 @@ function getDomainFromPipeline(inputKey: string) {
|
||||
let targetStepId = getStepIdFromInputKey(inputKey);
|
||||
let certStep = findStepFromPipeline(targetStepId);
|
||||
if (!certStep) {
|
||||
errorRef.value = t("certd.pluginCommon.targetStepNotFound");
|
||||
errorRef.value = t("certd.common.pluginCommon.targetStepNotFound");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ function getDomainFromPipeline(inputKey: string) {
|
||||
targetStepId = getStepIdFromInputKey(firstLevelValue);
|
||||
certStep = findStepFromPipeline(targetStepId);
|
||||
if (!certStep) {
|
||||
errorRef.value = t("certd.pluginCommon.targetStepNotFound");
|
||||
errorRef.value = t("certd.common.pluginCommon.targetStepNotFound");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<div class="domain-select">
|
||||
<div class="flex flex-row">
|
||||
<a-select
|
||||
@@ -18,12 +18,12 @@
|
||||
<template v-if="search">
|
||||
<div class="flex w-full items-center justify-between flex-wrap" style="padding: 4px 8px">
|
||||
<div class="flex-1 flex flex-row items-center">
|
||||
<a-input ref="inputRef" v-model:value="searchKeyRef" class="flex-1" allow-clear :placeholder="t('certd.pluginCommon.domainSearchPlaceholder')" @keydown.enter="doSearch" />
|
||||
<fs-button type="primary" class="m-1" :loading="loading" icon="mingcute:search-2-line" @click="doSearch">{{ t("certd.pluginCommon.search") }}</fs-button>
|
||||
<a-input ref="inputRef" v-model:value="searchKeyRef" class="flex-1" allow-clear :placeholder="t('certd.common.pluginCommon.domainSearchPlaceholder')" @keydown.enter="doSearch" />
|
||||
<fs-button type="primary" class="m-1" :loading="loading" icon="mingcute:search-2-line" @click="doSearch">{{ t("certd.common.pluginCommon.search") }}</fs-button>
|
||||
</div>
|
||||
<div class="manager flex flex-row items-center">
|
||||
<fs-button type="primary" class="m-1" icon="mingcute:vip-1-line" @click="openDomainImportDialog">{{ t("certd.pluginCommon.importDomain") }}</fs-button>
|
||||
<fs-button class="m-1" type="primary" icon="carbon:gui-management" @click="openDomainManager">{{ t("certd.pluginCommon.manageDomain") }}</fs-button>
|
||||
<fs-button type="primary" class="m-1" icon="mingcute:vip-1-line" @click="openDomainImportDialog">{{ t("certd.common.pluginCommon.importDomain") }}</fs-button>
|
||||
<fs-button class="m-1" type="primary" icon="carbon:gui-management" @click="openDomainManager">{{ t("certd.common.pluginCommon.manageDomain") }}</fs-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="hasError" class="helper p-2" :class="{ error: hasError }">
|
||||
@@ -49,7 +49,7 @@
|
||||
</a-select>
|
||||
<div class="ml-5 flex flex-row items-center">
|
||||
<fs-button title="复制全部域名" icon="ion:copy-outline" class="domain-select-copy-icon mr-5" @click="copySelectedDomains" />
|
||||
<fs-button :loading="loading" :title="t('certd.pluginCommon.refreshMyDomains')" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
<fs-button :loading="loading" :title="t('certd.common.pluginCommon.refreshMyDomains')" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="helper" :class="{ error: hasError }">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<a-auto-complete class="remote-auto-complete-input" :filter-option="filterOption" :options="optionsRef" :value="value" v-bind="attrs" @click="onClick" @update:value="emit('update:value', $event)">
|
||||
</a-auto-complete>
|
||||
<div class="ml-5">
|
||||
<fs-button :loading="loading" :title="t('certd.pluginCommon.refreshOptions')" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
<fs-button :loading="loading" :title="t('certd.common.pluginCommon.refreshOptions')" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="helper" :class="{ error: hasError }">
|
||||
@@ -96,16 +96,16 @@ const getOptions = async () => {
|
||||
{
|
||||
onError(err: any) {
|
||||
hasError.value = true;
|
||||
message.value = t("certd.pluginCommon.getOptionsError", { message: err.message });
|
||||
message.value = t("certd.common.pluginCommon.getOptionsError", { message: err.message });
|
||||
},
|
||||
showErrorNotify: false,
|
||||
}
|
||||
);
|
||||
const list = res?.list || res || [];
|
||||
if (list.length > 0) {
|
||||
message.value = t("certd.pluginCommon.getDataSuccessSelect");
|
||||
message.value = t("certd.common.pluginCommon.getDataSuccessSelect");
|
||||
} else {
|
||||
message.value = t("certd.pluginCommon.getDataSuccessEmpty");
|
||||
message.value = t("certd.common.pluginCommon.getDataSuccessEmpty");
|
||||
}
|
||||
optionsRef.value = list;
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ async function openDialog() {
|
||||
saveRemind: false,
|
||||
},
|
||||
afterSubmit() {
|
||||
notification.success({ message: t("certd.operationSuccess") });
|
||||
notification.success({ message: t("certd.common.operationSuccess") });
|
||||
},
|
||||
async doSubmit({ form }: any) {
|
||||
return await doPluginFormSubmit(form);
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
<template #dropdownRender="{ menuNode: menu }">
|
||||
<template v-if="search">
|
||||
<div class="flex w-full" style="padding: 4px 8px">
|
||||
<a-input ref="inputRef" v-model:value="searchKeyRef" class="flex-1" allow-clear :placeholder="t('certd.pluginCommon.searchKeyword')" @keydown.enter="doSearch" />
|
||||
<a-input ref="inputRef" v-model:value="searchKeyRef" class="flex-1" allow-clear :placeholder="t('certd.common.pluginCommon.searchKeyword')" @keydown.enter="doSearch" />
|
||||
<a-button class="ml-2" :loading="loading" type="text" @click="doSearch">
|
||||
<template #icon>
|
||||
<search-outlined />
|
||||
</template>
|
||||
{{ t("certd.pluginCommon.search") }}
|
||||
{{ t("certd.common.pluginCommon.search") }}
|
||||
</a-button>
|
||||
</div>
|
||||
<div v-if="hasError" class="helper p-2" :class="{ error: hasError }">
|
||||
@@ -26,7 +26,7 @@
|
||||
</template>
|
||||
</a-select>
|
||||
<div class="ml-5 flex flex-row no-wrap">
|
||||
<fs-button :loading="loading" :title="t('certd.pluginCommon.refreshOptions')" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
<fs-button :loading="loading" :title="t('certd.common.pluginCommon.refreshOptions')" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
<UploadCert v-if="uploadCert" class="ml-5" v-bind="uploadCert" @submit="refreshOptions"></UploadCert>
|
||||
</div>
|
||||
</div>
|
||||
@@ -177,7 +177,7 @@ const getOptions = async () => {
|
||||
{
|
||||
onError(err: any) {
|
||||
hasError.value = true;
|
||||
message.value = t("certd.pluginCommon.getOptionsError", { message: err.message });
|
||||
message.value = t("certd.common.pluginCommon.getOptionsError", { message: err.message });
|
||||
optionsRef.value = [];
|
||||
},
|
||||
showErrorNotify: false,
|
||||
@@ -185,9 +185,9 @@ const getOptions = async () => {
|
||||
);
|
||||
let list = res?.list || res || [];
|
||||
if (list.length > 0) {
|
||||
message.value = t("certd.pluginCommon.getDataSuccessSelect");
|
||||
message.value = t("certd.common.pluginCommon.getDataSuccessSelect");
|
||||
} else {
|
||||
message.value = t("certd.pluginCommon.getDataSuccessEmpty");
|
||||
message.value = t("certd.common.pluginCommon.getDataSuccessEmpty");
|
||||
}
|
||||
list = list.map((item: any) => {
|
||||
return {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="flex flex-row">
|
||||
<a-tree-select class="remote-tree-select-input" :tree-data="optionsRef" :value="value" tree-checkable allow-clear v-bind="attrs" @click="onClick" @update:value="emit('update:value', $event)"> </a-tree-select>
|
||||
<div class="ml-5">
|
||||
<fs-button :loading="loading" :title="t('certd.pluginCommon.refreshOptions')" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
<fs-button :loading="loading" :title="t('certd.common.pluginCommon.refreshOptions')" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="helper" :class="{ error: hasError }">
|
||||
@@ -107,16 +107,16 @@ const getOptions = async () => {
|
||||
{
|
||||
onError(err: any) {
|
||||
hasError.value = true;
|
||||
message.value = t("certd.pluginCommon.getOptionsError", { message: err.message });
|
||||
message.value = t("certd.common.pluginCommon.getOptionsError", { message: err.message });
|
||||
},
|
||||
showErrorNotify: false,
|
||||
}
|
||||
);
|
||||
const list = res?.list || res || [];
|
||||
if (list.length > 0) {
|
||||
message.value = t("certd.pluginCommon.getDataSuccessSelect");
|
||||
message.value = t("certd.common.pluginCommon.getDataSuccessSelect");
|
||||
} else {
|
||||
message.value = t("certd.pluginCommon.getDataSuccessEmpty");
|
||||
message.value = t("certd.common.pluginCommon.getDataSuccessEmpty");
|
||||
}
|
||||
optionsRef.value = list;
|
||||
pagerRef.value.total = list.length;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="upload-cert">
|
||||
<fs-button v-model:loading="loading" type="primary" :text="t('certd.pluginCommon.upload')" v-bind="props.button" @click="openUploadCertDialog"></fs-button>
|
||||
<fs-button v-model:loading="loading" type="primary" :text="t('certd.common.pluginCommon.upload')" v-bind="props.button" @click="openUploadCertDialog"></fs-button>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
@@ -30,18 +30,18 @@ const getScope: any = inject("get:scope", () => {
|
||||
const getPluginType: any = inject("get:plugin:type", () => {
|
||||
return "plugin";
|
||||
});
|
||||
const title = computed(() => props.title || t("certd.pluginCommon.uploadCert"));
|
||||
const title = computed(() => props.title || t("certd.common.pluginCommon.uploadCert"));
|
||||
function openUploadCertDialog() {
|
||||
const columns = merge(
|
||||
{
|
||||
certName: {
|
||||
title: t("certd.pluginCommon.certName"),
|
||||
title: t("certd.common.pluginCommon.certName"),
|
||||
form: {
|
||||
component: {
|
||||
name: "a-input",
|
||||
vModel: "value",
|
||||
},
|
||||
helper: t("certd.pluginCommon.certNameHelper"),
|
||||
helper: t("certd.common.pluginCommon.certNameHelper"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -51,7 +51,7 @@ function openUploadCertDialog() {
|
||||
title: title.value,
|
||||
columns: {
|
||||
certName: {
|
||||
title: t("certd.pluginCommon.certName"),
|
||||
title: t("certd.common.pluginCommon.certName"),
|
||||
form: {
|
||||
component: {
|
||||
name: "a-input",
|
||||
@@ -86,7 +86,7 @@ function openUploadCertDialog() {
|
||||
showErrorNotify: true,
|
||||
}
|
||||
);
|
||||
notification.success({ message: t("certd.pluginCommon.uploadSuccess") });
|
||||
notification.success({ message: t("certd.common.pluginCommon.uploadSuccess") });
|
||||
emit("submit");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
|
||||
@@ -4,10 +4,10 @@ import { $t } from "/@/locales";
|
||||
function createChallengeTypeDict() {
|
||||
return dict({
|
||||
data: [
|
||||
{ value: "dns", label: $t("certd.verifyPlan.dnsChallenge"), color: "green" },
|
||||
{ value: "dns", label: $t("certd.certdomain.verifyPlan.dnsChallenge"), color: "green" },
|
||||
{ value: "dns-persist", label: "DNS持久验证", color: "cyan" },
|
||||
{ value: "cname", label: $t("certd.verifyPlan.cnameProxyChallenge"), color: "blue" },
|
||||
{ value: "http", label: $t("certd.verifyPlan.httpChallenge"), color: "yellow" },
|
||||
{ value: "cname", label: $t("certd.certdomain.verifyPlan.cnameProxyChallenge"), color: "blue" },
|
||||
{ value: "http", label: $t("certd.certdomain.verifyPlan.httpChallenge"), color: "yellow" },
|
||||
],
|
||||
});
|
||||
}
|
||||
@@ -18,11 +18,11 @@ function createUploaderTypeDict() {
|
||||
{ label: "SFTP", value: "sftp" },
|
||||
{ label: "SCP", value: "scp" },
|
||||
{ label: "FTP", value: "ftp" },
|
||||
{ label: $t("certd.verifyPlan.uploader.aliyunOss"), value: "alioss" },
|
||||
{ label: $t("certd.verifyPlan.uploader.tencentCos"), value: "tencentcos" },
|
||||
{ label: $t("certd.verifyPlan.uploader.qiniuOss"), value: "qiniuoss" },
|
||||
{ label: $t("certd.certdomain.verifyPlan.uploader.aliyunOss"), value: "alioss" },
|
||||
{ label: $t("certd.certdomain.verifyPlan.uploader.tencentCos"), value: "tencentcos" },
|
||||
{ label: $t("certd.certdomain.verifyPlan.uploader.qiniuOss"), value: "qiniuoss" },
|
||||
{ label: "S3/Minio", value: "s3" },
|
||||
{ label: $t("certd.verifyPlan.uploader.sshDeprecated"), value: "ssh", disabled: true },
|
||||
{ label: $t("certd.certdomain.verifyPlan.uploader.sshDeprecated"), value: "ssh", disabled: true },
|
||||
],
|
||||
});
|
||||
}
|
||||
@@ -30,8 +30,8 @@ function createUploaderTypeDict() {
|
||||
function createDomainFromTypeDict() {
|
||||
return dict({
|
||||
data: [
|
||||
{ value: "manual", label: $t("certd.verifyPlan.domainFrom.manual") },
|
||||
{ value: "auto", label: $t("certd.verifyPlan.domainFrom.auto") },
|
||||
{ value: "manual", label: $t("certd.certdomain.verifyPlan.domainFrom.manual") },
|
||||
{ value: "auto", label: $t("certd.certdomain.verifyPlan.domainFrom.auto") },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -33,11 +33,11 @@ const { t } = useI18n();
|
||||
<div class="tutorial-button pointer" @click="open">
|
||||
<template v-if="!slots.default">
|
||||
<fs-icon v-if="showIcon === false" icon="ant-design:question-circle-outlined" class="mr-0.5"></fs-icon>
|
||||
<div class="hidden md:block">{{ t("tutorial.title") }}</div>
|
||||
<div class="hidden md:block">{{ t("certd.tutorial.title") }}</div>
|
||||
</template>
|
||||
<slot></slot>
|
||||
<a-modal v-model:open="openedRef" class="tutorial-modal" width="90%">
|
||||
<template #title>{{ t("tutorial.title") }}</template>
|
||||
<template #title>{{ t("certd.tutorial.title") }}</template>
|
||||
<tutorial-steps v-if="openedRef" />
|
||||
<template #footer></template>
|
||||
</a-modal>
|
||||
|
||||
@@ -18,9 +18,9 @@ import { ref } from "vue";
|
||||
import { mitter } from "/@/utils/util.mitt";
|
||||
|
||||
const steps = ref<Step[]>([
|
||||
{ title: t("certd.steps.createPipeline"), icon: <fs-icon icon="tabler:circle-number-1-filled"></fs-icon> },
|
||||
{ title: t("certd.steps.addTask"), icon: <fs-icon icon="tabler:circle-number-2-filled"></fs-icon> },
|
||||
{ title: t("certd.steps.scheduledRun"), icon: <fs-icon icon="tabler:circle-number-3-filled"></fs-icon> },
|
||||
{ title: t("certd.tutorial.steps.createPipeline"), icon: <fs-icon icon="tabler:circle-number-1-filled"></fs-icon> },
|
||||
{ title: t("certd.tutorial.steps.addTask"), icon: <fs-icon icon="tabler:circle-number-2-filled"></fs-icon> },
|
||||
{ title: t("certd.tutorial.steps.scheduledRun"), icon: <fs-icon icon="tabler:circle-number-3-filled"></fs-icon> },
|
||||
]);
|
||||
|
||||
function goPipeline() {
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
</div>
|
||||
|
||||
<div class="flex-center actions">
|
||||
<fs-button class="m-10" icon="ion:arrow-back-outline" @click="prev()">{{ t("guide.buttons.prev") }}</fs-button>
|
||||
<fs-button class="m-10" type="primary" icon-right="ion:arrow-forward-outline" @click="next()">{{ t("guide.buttons.next") }}</fs-button>
|
||||
<fs-button class="m-10" icon="ion:arrow-back-outline" @click="prev()">{{ t("certd.guide.buttons.prev") }}</fs-button>
|
||||
<fs-button class="m-10" type="primary" icon-right="ion:arrow-forward-outline" @click="next()">{{ t("certd.guide.buttons.next") }}</fs-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -52,126 +52,126 @@ import { computed, nextTick, ref } from "vue";
|
||||
|
||||
const steps = ref<Step[]>([
|
||||
{
|
||||
title: t("guide.createCertPipeline.title"),
|
||||
description: t("guide.createCertPipeline.description"),
|
||||
title: t("certd.guide.createCertPipeline.title"),
|
||||
description: t("certd.guide.createCertPipeline.description"),
|
||||
items: [
|
||||
{
|
||||
title: t("guide.createCertPipeline.items.tutorialTitle"),
|
||||
descriptions: [t("guide.createCertPipeline.items.tutorialDesc1"), t("guide.createCertPipeline.items.tutorialDesc2")],
|
||||
title: t("certd.guide.createCertPipeline.items.tutorialTitle"),
|
||||
descriptions: [t("certd.guide.createCertPipeline.items.tutorialDesc1"), t("certd.guide.createCertPipeline.items.tutorialDesc2")],
|
||||
body: () => {
|
||||
return <SimpleSteps></SimpleSteps>;
|
||||
},
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/1-add.png",
|
||||
title: t("guide.createCertPipeline.items.createTitle"),
|
||||
descriptions: [t("guide.createCertPipeline.items.createDesc")],
|
||||
title: t("certd.guide.createCertPipeline.items.createTitle"),
|
||||
descriptions: [t("certd.guide.createCertPipeline.items.createDesc")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/3-add-success.png",
|
||||
title: t("guide.createCertPipeline.items.successTitle"),
|
||||
descriptions: [t("guide.createCertPipeline.items.successDesc")],
|
||||
title: t("certd.guide.createCertPipeline.items.successTitle"),
|
||||
descriptions: [t("certd.guide.createCertPipeline.items.successDesc")],
|
||||
},
|
||||
// {
|
||||
// title: t("guide.createCertPipeline.items.nextTitle"),
|
||||
// descriptions: [t("guide.createCertPipeline.items.nextDesc")],
|
||||
// title: t("certd.guide.createCertPipeline.items.nextTitle"),
|
||||
// descriptions: [t("certd.guide.createCertPipeline.items.nextDesc")],
|
||||
// },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: t("guide.addDeployTask.title"),
|
||||
description: t("guide.addDeployTask.description"),
|
||||
title: t("certd.guide.addDeployTask.title"),
|
||||
description: t("certd.guide.addDeployTask.description"),
|
||||
items: [
|
||||
{
|
||||
image: "/static/doc/images/5-1-add-host.png",
|
||||
title: t("guide.addDeployTask.items.addTaskTitle"),
|
||||
descriptions: [t("guide.addDeployTask.items.addTaskDesc1"), t("guide.addDeployTask.items.addTaskDesc2")],
|
||||
title: t("certd.guide.addDeployTask.items.addTaskTitle"),
|
||||
descriptions: [t("certd.guide.addDeployTask.items.addTaskDesc1"), t("certd.guide.addDeployTask.items.addTaskDesc2")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/5-2-add-host.png",
|
||||
title: t("guide.addDeployTask.items.fillParamsTitle"),
|
||||
descriptions: [t("guide.addDeployTask.items.fillParamsDesc1"), t("guide.addDeployTask.items.fillParamsDesc2")],
|
||||
title: t("certd.guide.addDeployTask.items.fillParamsTitle"),
|
||||
descriptions: [t("certd.guide.addDeployTask.items.fillParamsDesc1"), t("certd.guide.addDeployTask.items.fillParamsDesc2")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/5-3-add-host.png",
|
||||
title: t("guide.addDeployTask.items.activateCertTitle"),
|
||||
descriptions: [t("guide.addDeployTask.items.activateCertDesc1"), t("guide.addDeployTask.items.activateCertDesc2")],
|
||||
title: t("certd.guide.addDeployTask.items.activateCertTitle"),
|
||||
descriptions: [t("certd.guide.addDeployTask.items.activateCertDesc1"), t("certd.guide.addDeployTask.items.activateCertDesc2")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/5-4-add-host.png",
|
||||
title: t("guide.addDeployTask.items.taskSuccessTitle"),
|
||||
descriptions: [t("guide.addDeployTask.items.taskSuccessDesc")],
|
||||
title: t("certd.guide.addDeployTask.items.taskSuccessTitle"),
|
||||
descriptions: [t("certd.guide.addDeployTask.items.taskSuccessDesc")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/5-5-plugin-list.png",
|
||||
title: t("guide.addDeployTask.items.pluginsTitle"),
|
||||
descriptions: [t("guide.addDeployTask.items.pluginsDesc")],
|
||||
title: t("certd.guide.addDeployTask.items.pluginsTitle"),
|
||||
descriptions: [t("certd.guide.addDeployTask.items.pluginsDesc")],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: t("guide.runAndTestTask.runAndTestTitle"),
|
||||
description: t("guide.runAndTestTask.runAndTestDescription"),
|
||||
title: t("certd.guide.runAndTestTask.runAndTestTitle"),
|
||||
description: t("certd.guide.runAndTestTask.runAndTestDescription"),
|
||||
items: [
|
||||
{
|
||||
image: "/static/doc/images/9-start.png",
|
||||
title: t("guide.runAndTestTask.runTestOnce"),
|
||||
descriptions: [t("guide.runAndTestTask.clickManualTriggerToTest")],
|
||||
title: t("certd.guide.runAndTestTask.runTestOnce"),
|
||||
descriptions: [t("certd.guide.runAndTestTask.clickManualTriggerToTest")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/10-1-log.png",
|
||||
title: t("guide.runAndTestTask.viewLogs"),
|
||||
descriptions: [t("guide.runAndTestTask.clickTaskToViewStatusAndLogs")],
|
||||
title: t("certd.guide.runAndTestTask.viewLogs"),
|
||||
descriptions: [t("certd.guide.runAndTestTask.clickTaskToViewStatusAndLogs")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/11-1-error.png",
|
||||
title: t("guide.runAndTestTask.howToTroubleshootFailure"),
|
||||
descriptions: [t("guide.runAndTestTask.viewErrorLogs")],
|
||||
title: t("certd.guide.runAndTestTask.howToTroubleshootFailure"),
|
||||
descriptions: [t("certd.guide.runAndTestTask.viewErrorLogs")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/11-2-error.png",
|
||||
title: t("guide.runAndTestTask.howToTroubleshootFailure"),
|
||||
descriptions: [t("guide.runAndTestTask.viewErrorLogs"), t("guide.runAndTestTask.nginxContainerNotExistFix")],
|
||||
title: t("certd.guide.runAndTestTask.howToTroubleshootFailure"),
|
||||
descriptions: [t("certd.guide.runAndTestTask.viewErrorLogs"), t("certd.guide.runAndTestTask.nginxContainerNotExistFix")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/12-1-log-success.png",
|
||||
title: t("guide.runAndTestTask.executionSuccess"),
|
||||
descriptions: [t("guide.runAndTestTask.retryAfterFix")],
|
||||
title: t("certd.guide.runAndTestTask.executionSuccess"),
|
||||
descriptions: [t("certd.guide.runAndTestTask.retryAfterFix")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/12-2-skip-log.png",
|
||||
title: t("guide.runAndTestTask.autoSkipAfterSuccess"),
|
||||
descriptions: [t("guide.runAndTestTask.successSkipExplanation")],
|
||||
title: t("certd.guide.runAndTestTask.autoSkipAfterSuccess"),
|
||||
descriptions: [t("certd.guide.runAndTestTask.successSkipExplanation")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/13-1-result.png",
|
||||
title: t("guide.runAndTestTask.viewCertDeploymentSuccess"),
|
||||
descriptions: [t("guide.runAndTestTask.visitNginxToSeeCert")],
|
||||
title: t("certd.guide.runAndTestTask.viewCertDeploymentSuccess"),
|
||||
descriptions: [t("certd.guide.runAndTestTask.visitNginxToSeeCert")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/13-3-download.png",
|
||||
title: t("guide.runAndTestTask.downloadCertManualDeploy"),
|
||||
descriptions: [t("guide.runAndTestTask.downloadIfNoAutoDeployPlugin")],
|
||||
title: t("certd.guide.runAndTestTask.downloadCertManualDeploy"),
|
||||
descriptions: [t("certd.guide.runAndTestTask.downloadIfNoAutoDeployPlugin")],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: t("guide.scheduleAndEmailTask.title"),
|
||||
description: t("guide.scheduleAndEmailTask.description"),
|
||||
title: t("certd.guide.scheduleAndEmailTask.title"),
|
||||
description: t("certd.guide.scheduleAndEmailTask.description"),
|
||||
items: [
|
||||
{
|
||||
image: "/static/doc/images/14-timer.png",
|
||||
title: t("guide.scheduleAndEmailTask.setSchedule"),
|
||||
descriptions: [t("guide.scheduleAndEmailTask.pipelineSuccessThenSchedule"), t("guide.scheduleAndEmailTask.recommendDailyRun")],
|
||||
title: t("certd.guide.scheduleAndEmailTask.setSchedule"),
|
||||
descriptions: [t("certd.guide.scheduleAndEmailTask.pipelineSuccessThenSchedule"), t("certd.guide.scheduleAndEmailTask.recommendDailyRun")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/15-1-email.png",
|
||||
title: t("guide.scheduleAndEmailTask.setEmailNotification"),
|
||||
descriptions: [t("guide.scheduleAndEmailTask.suggestErrorAndRecoveryEmails")],
|
||||
title: t("certd.guide.scheduleAndEmailTask.setEmailNotification"),
|
||||
descriptions: [t("certd.guide.scheduleAndEmailTask.suggestErrorAndRecoveryEmails")],
|
||||
},
|
||||
{
|
||||
title: t("guide.scheduleAndEmailTask.tutorialEndTitle"),
|
||||
descriptions: [t("guide.scheduleAndEmailTask.thanksForWatching")],
|
||||
title: t("certd.guide.scheduleAndEmailTask.tutorialEndTitle"),
|
||||
descriptions: [t("certd.guide.scheduleAndEmailTask.thanksForWatching")],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -48,56 +48,56 @@ const text = computed<Text>(() => {
|
||||
const map = {
|
||||
isComm: {
|
||||
comm: {
|
||||
name: t("vip.comm.name", { vipLabel }),
|
||||
title: t("vip.comm.title", { expire: expireTime.value }),
|
||||
name: t("certd.vip.comm.name", { vipLabel }),
|
||||
title: t("certd.vip.comm.title", { expire: expireTime.value }),
|
||||
},
|
||||
button: {
|
||||
name: t("vip.comm.name", { vipLabel }),
|
||||
title: t("vip.comm.title", { expire: expireTime.value }),
|
||||
name: t("certd.vip.comm.name", { vipLabel }),
|
||||
title: t("certd.vip.comm.title", { expire: expireTime.value }),
|
||||
},
|
||||
icon: {
|
||||
name: "",
|
||||
title: t("vip.comm.name", { vipLabel }),
|
||||
title: t("certd.vip.comm.name", { vipLabel }),
|
||||
},
|
||||
nav: {
|
||||
name: t("vip.comm.nav", { vipLabel }),
|
||||
title: t("vip.comm.title", { expire: expireTime.value }),
|
||||
name: t("certd.vip.comm.nav", { vipLabel }),
|
||||
title: t("certd.vip.comm.title", { expire: expireTime.value }),
|
||||
},
|
||||
},
|
||||
isPlus: {
|
||||
comm: {
|
||||
name: t("vip.plus.name"),
|
||||
title: t("vip.plus.title"),
|
||||
name: t("certd.vip.plus.name"),
|
||||
title: t("certd.vip.plus.title"),
|
||||
},
|
||||
button: {
|
||||
name: t("vip.comm.name", { vipLabel }),
|
||||
title: t("vip.comm.title", { expire: expireTime.value }),
|
||||
name: t("certd.vip.comm.name", { vipLabel }),
|
||||
title: t("certd.vip.comm.title", { expire: expireTime.value }),
|
||||
},
|
||||
icon: {
|
||||
name: "",
|
||||
title: t("vip.comm.name", { vipLabel }),
|
||||
title: t("certd.vip.comm.name", { vipLabel }),
|
||||
},
|
||||
nav: {
|
||||
name: t("vip.comm.nav", { vipLabel }),
|
||||
title: t("vip.comm.title", { expire: expireTime.value }),
|
||||
name: t("certd.vip.comm.nav", { vipLabel }),
|
||||
title: t("certd.vip.comm.title", { expire: expireTime.value }),
|
||||
},
|
||||
},
|
||||
free: {
|
||||
comm: {
|
||||
name: t("vip.free.comm.name"),
|
||||
title: t("vip.free.comm.title"),
|
||||
name: t("certd.vip.free.comm.name"),
|
||||
title: t("certd.vip.free.comm.title"),
|
||||
},
|
||||
button: {
|
||||
name: t("vip.free.button.name"),
|
||||
title: t("vip.free.button.title"),
|
||||
name: t("certd.vip.free.button.name"),
|
||||
title: t("certd.vip.free.button.title"),
|
||||
},
|
||||
icon: {
|
||||
name: "",
|
||||
title: t("vip.free.button.name"),
|
||||
title: t("certd.vip.free.button.name"),
|
||||
},
|
||||
nav: {
|
||||
name: t("vip.free.nav.name"),
|
||||
title: plusMessage || t("vip.free.nav.title"),
|
||||
name: t("certd.vip.free.nav.name"),
|
||||
title: plusMessage || t("certd.vip.free.nav.title"),
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -131,7 +131,7 @@ const userStore = useUserStore();
|
||||
|
||||
async function getVipTrial(vipType = "plus") {
|
||||
const res = await api.getVipTrial(vipType);
|
||||
notification.success({ message: t("vip.congratulations_vip_trial", { duration: res.duration }) });
|
||||
notification.success({ message: t("certd.vip.congratulations_vip_trial", { duration: res.duration }) });
|
||||
await settingStore.init();
|
||||
}
|
||||
|
||||
@@ -139,8 +139,8 @@ function openTrialModal(vipType = "plus") {
|
||||
Modal.destroyAll();
|
||||
|
||||
modal.confirm({
|
||||
title: t("vip.trial_modal_title"),
|
||||
okText: t("vip.trial_modal_ok_text"),
|
||||
title: t("certd.vip.trial_modal_title"),
|
||||
okText: t("certd.vip.trial_modal_ok_text"),
|
||||
onOk() {
|
||||
getVipTrial(vipType);
|
||||
},
|
||||
@@ -148,8 +148,8 @@ function openTrialModal(vipType = "plus") {
|
||||
content: () => {
|
||||
return (
|
||||
<div class="flex-col mt-10 mb-10">
|
||||
<div>{t("vip.trial_modal_thanks")}</div>
|
||||
<div>{t("vip.trial_modal_click_confirm", { vipType })}</div>
|
||||
<div>{t("certd.vip.trial_modal_thanks")}</div>
|
||||
<div>{t("certd.vip.trial_modal_click_confirm", { vipType })}</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
@@ -158,7 +158,7 @@ function openTrialModal(vipType = "plus") {
|
||||
|
||||
function openStarModal(vipType: string) {
|
||||
if (settingStore.isPlus) {
|
||||
notification.error({ message: t("vip.already_vip") });
|
||||
notification.error({ message: t("certd.vip.already_vip") });
|
||||
return;
|
||||
}
|
||||
Modal.destroyAll();
|
||||
@@ -170,8 +170,8 @@ function openStarModal(vipType: string) {
|
||||
// };
|
||||
|
||||
// modal.confirm({
|
||||
// title: t("vip.get_7_day_pro_trial"),
|
||||
// okText: t("vip.star_now"),
|
||||
// title: t("certd.vip.get_7_day_pro_trial"),
|
||||
// okText: t("certd.vip.star_now"),
|
||||
// onOk() {
|
||||
// goGithub();
|
||||
// openTrialModal(vipType);
|
||||
@@ -180,7 +180,7 @@ function openStarModal(vipType: string) {
|
||||
// content: () => {
|
||||
// return (
|
||||
// <div class="flex mt-10 mb-10">
|
||||
// <div>{t("vip.please_help_star")}</div>
|
||||
// <div>{t("certd.vip.please_help_star")}</div>
|
||||
// <img class="ml-5" src="https://img.shields.io/github/stars/certd/certd?logo=github" />
|
||||
// </div>
|
||||
// );
|
||||
@@ -190,16 +190,16 @@ function openStarModal(vipType: string) {
|
||||
|
||||
function openUpgrade() {
|
||||
if (!userStore.isAdmin) {
|
||||
notification.info({ message: t("vip.admin_only_operation") });
|
||||
notification.info({ message: t("certd.vip.admin_only_operation") });
|
||||
return;
|
||||
}
|
||||
const placeholder = t("vip.enter_activation_code");
|
||||
const placeholder = t("certd.vip.enter_activation_code");
|
||||
const isPlus = settingStore.isPlus;
|
||||
let title = t("vip.activate_pro_business");
|
||||
let title = t("certd.vip.activate_pro_business");
|
||||
if (settingStore.isComm) {
|
||||
title = t("vip.renew_business");
|
||||
title = t("certd.vip.renew_business");
|
||||
} else if (settingStore.isPlus) {
|
||||
title = t("vip.renew_pro_upgrade_business");
|
||||
title = t("certd.vip.renew_pro_upgrade_business");
|
||||
}
|
||||
|
||||
// const goBuyUrl = "https://afdian.com/a/greper"
|
||||
@@ -214,10 +214,10 @@ function openUpgrade() {
|
||||
function checkPerpetualPlus() {
|
||||
if (settingStore.isPerpetual) {
|
||||
Modal.warn({
|
||||
title: t("vip.already_perpetual_plus"),
|
||||
okText: t("vip.confirm"),
|
||||
title: t("certd.vip.already_perpetual_plus"),
|
||||
okText: t("certd.vip.confirm"),
|
||||
});
|
||||
throw new Error(t("vip.already_perpetual_plus"));
|
||||
throw new Error(t("certd.vip.already_perpetual_plus"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,8 +225,8 @@ function openUpgrade() {
|
||||
checkPerpetualPlus();
|
||||
if (settingStore.isComm) {
|
||||
Modal.warn({
|
||||
title: t("vip.already_comm"),
|
||||
okText: t("vip.confirm"),
|
||||
title: t("certd.vip.already_comm"),
|
||||
okText: t("certd.vip.confirm"),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -237,8 +237,8 @@ function openUpgrade() {
|
||||
checkPerpetualPlus();
|
||||
if (settingStore.isPlus && !settingStore.isComm) {
|
||||
Modal.confirm({
|
||||
title: t("vip.already_plus"),
|
||||
okText: t("vip.confirm"),
|
||||
title: t("certd.vip.already_plus"),
|
||||
okText: t("certd.vip.confirm"),
|
||||
onOk() {
|
||||
window.open(goBuyCommUrl);
|
||||
},
|
||||
@@ -251,7 +251,7 @@ function openUpgrade() {
|
||||
title,
|
||||
class: "vip-modal",
|
||||
maskClosable: true,
|
||||
okText: t("vip.close"),
|
||||
okText: t("certd.vip.close"),
|
||||
width: 1180,
|
||||
content: () => {
|
||||
return <VipModalContent placeholder={placeholder} isPlus={isPlus} productInfo={productInfo} goBuyPlusPage={goBuyPlusPage} goBuyCommPage={goBuyCommPage} openStarModal={openStarModal} modalRef={modalRef} />;
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
</a-tooltip>
|
||||
</span>
|
||||
<span v-else>
|
||||
<span class="price-text">{{ t("vip.freee") }}</span>
|
||||
<span class="price-text">{{ t("certd.vip.freee") }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="get-show">
|
||||
@@ -44,15 +44,15 @@
|
||||
<span class="color-red"> {{ todayOrderCount.vipTotal }}</span>
|
||||
位伙伴支持
|
||||
</span>
|
||||
<a-tooltip :title="t('vip.afdian_support_vip')">
|
||||
<a-tooltip :title="t('certd.vip.afdian_support_vip')">
|
||||
<a-button size="small" type="primary" @click="goBuyPlusPage">
|
||||
{{ t("vip.get_after_support") }}
|
||||
{{ t("certd.vip.get_after_support") }}
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-else-if="item.type === 'comm'">
|
||||
<a-button size="small" type="primary" @click="goBuyCommPage">
|
||||
{{ t("vip.buy") }}
|
||||
{{ t("certd.vip.buy") }}
|
||||
</a-button>
|
||||
</template>
|
||||
</div>
|
||||
@@ -63,36 +63,36 @@
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://certd.docmirror.cn/guide/donate/#相关问题" target="_blank">
|
||||
{{ t("vip.question") }}
|
||||
{{ t("certd.vip.question") }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="mt-10">
|
||||
<div class="w-100 flex-col md:flex-row">
|
||||
<span>{{ t("vip.site_id") }}:</span>
|
||||
<span>{{ t("certd.vip.site_id") }}:</span>
|
||||
<fs-copyable v-model="computedSiteId" class="mr-2 inline-flex"></fs-copyable>
|
||||
<a @click="goBindAccount">{{ t("vip.not_effective") }}</a>
|
||||
<a @click="goBindAccount">{{ t("certd.vip.not_effective") }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isPlus" class="mt-10 flex flex-col md:flex-row">
|
||||
<span class="mr-2"> {{ t("vip.current") }} {{ vipLabel }} {{ t("vip.activated_expire_time") }} {{ settingStore.expiresText }} </span>
|
||||
<span class="mr-2"> {{ t("certd.vip.current") }} {{ vipLabel }} {{ t("certd.vip.activated_expire_time") }} {{ settingStore.expiresText }} </span>
|
||||
<a href="https://app.handfree.work/subject/#/page/detail/1" target="_blank">
|
||||
{{ t("vip.learn_more") }}
|
||||
{{ t("certd.vip.learn_more") }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="mt-10">
|
||||
<span class="mr-2">{{ t("vip.have_activation_code") }}</span>
|
||||
<span class="mr-2">{{ t("certd.vip.have_activation_code") }}</span>
|
||||
<span>
|
||||
<a @click="showManualActivation">{{ t("vip.manual_activation") }}</a>
|
||||
<a @click="showManualActivation">{{ t("certd.vip.manual_activation") }}</a>
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="manualActiveFlag" class="mt-10">
|
||||
<div class="mt-10">
|
||||
<a-input-search v-model:value="formState.code" class="w-2/6" :placeholder="placeholder" :enter-button="t('vip.activate')" @search="doActive"></a-input-search>
|
||||
<a-input-search v-model:value="formState.code" class="w-2/6" :placeholder="placeholder" :enter-button="t('certd.vip.activate')" @search="doActive"></a-input-search>
|
||||
</div>
|
||||
<div class="mt-10">
|
||||
{{ t("vip.activation_code_one_use") }}
|
||||
<a @click="goAccount">{{ t("vip.bind_account") }}</a
|
||||
>,{{ t("vip.transfer_vip") }}
|
||||
{{ t("certd.vip.activation_code_one_use") }}
|
||||
<a @click="goAccount">{{ t("certd.vip.bind_account") }}</a
|
||||
>,{{ t("certd.vip.transfer_vip") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -128,24 +128,24 @@ const formState = reactive({
|
||||
|
||||
async function doActive() {
|
||||
if (!formState.code) {
|
||||
notification.error({ message: t("vip.enterCode") });
|
||||
throw new Error(t("vip.enterCode"));
|
||||
notification.error({ message: t("certd.vip.enterCode") });
|
||||
throw new Error(t("certd.vip.enterCode"));
|
||||
}
|
||||
const res = await api.doActive(formState);
|
||||
if (res) {
|
||||
await settingStore.init();
|
||||
const vipLabel = settingStore.vipLabel;
|
||||
Modal.success({
|
||||
title: t("vip.successTitle"),
|
||||
content: t("vip.successContent", {
|
||||
title: t("certd.vip.successTitle"),
|
||||
content: t("certd.vip.successContent", {
|
||||
vipLabel,
|
||||
expireDate: settingStore.plusInfo.expireTime === -1 ? t("vip.permanent") : dayjs(settingStore.plusInfo.expireTime).format("YYYY-MM-DD"),
|
||||
expireDate: settingStore.plusInfo.expireTime === -1 ? t("certd.vip.permanent") : dayjs(settingStore.plusInfo.expireTime).format("YYYY-MM-DD"),
|
||||
}),
|
||||
onOk() {
|
||||
if (!(settingStore.installInfo.bindUserId > 0)) {
|
||||
Modal.confirm({
|
||||
title: t("vip.bindAccountTitle"),
|
||||
content: t("vip.bindAccountContent"),
|
||||
title: t("certd.vip.bindAccountTitle"),
|
||||
content: t("certd.vip.bindAccountContent"),
|
||||
onOk() {
|
||||
router.push("/sys/account");
|
||||
},
|
||||
@@ -179,39 +179,39 @@ function goBindAccount() {
|
||||
|
||||
const vipTypeDefine: any = {
|
||||
free: {
|
||||
title: t("vip.basic_edition"),
|
||||
desc: t("vip.community_free_version"),
|
||||
title: t("certd.vip.basic_edition"),
|
||||
desc: t("certd.vip.community_free_version"),
|
||||
type: "free",
|
||||
icon: "lucide:package-open",
|
||||
privilege: t("vip.free_privilege").split("\n"),
|
||||
privilege: t("certd.vip.free_privilege").split("\n"),
|
||||
},
|
||||
plus: {
|
||||
title: t("vip.professional_edition"),
|
||||
desc: t("vip.open_source_support"),
|
||||
title: t("certd.vip.professional_edition"),
|
||||
desc: t("certd.vip.open_source_support"),
|
||||
type: "plus",
|
||||
privilege: t("vip.plus_privilege").split("\n"),
|
||||
privilege: t("certd.vip.plus_privilege").split("\n"),
|
||||
trial: {
|
||||
title: t("vip.click_to_get_7_day_trial"),
|
||||
title: t("certd.vip.click_to_get_7_day_trial"),
|
||||
click: () => {
|
||||
props.openStarModal("plus");
|
||||
},
|
||||
},
|
||||
icon: "stash:thumb-up",
|
||||
priceText: props.productInfo.plus.priceText || `¥${props.productInfo.plus.price}/${t("vip.years")}`,
|
||||
discountText: props.productInfo.plus.discountText || `¥${props.productInfo.plus.price3}/3${t("vip.years")}`,
|
||||
priceText: props.productInfo.plus.priceText || `¥${props.productInfo.plus.price}/${t("certd.vip.years")}`,
|
||||
discountText: props.productInfo.plus.discountText || `¥${props.productInfo.plus.price3}/3${t("certd.vip.years")}`,
|
||||
tooltip: props.productInfo.plus.tooltip,
|
||||
},
|
||||
comm: {
|
||||
title: t("vip.business_edition"),
|
||||
desc: t("vip.commercial_license"),
|
||||
title: t("certd.vip.business_edition"),
|
||||
desc: t("certd.vip.commercial_license"),
|
||||
type: "comm",
|
||||
icon: "vaadin:handshake",
|
||||
privilege: t("vip.comm_privilege").split("\n"),
|
||||
priceText: props.productInfo.comm.priceText || `¥${props.productInfo.comm.price}/${t("vip.years")}`,
|
||||
discountText: props.productInfo.comm.discountText || `¥${props.productInfo.comm.price3}/3${t("vip.years")}`,
|
||||
privilege: t("certd.vip.comm_privilege").split("\n"),
|
||||
priceText: props.productInfo.comm.priceText || `¥${props.productInfo.comm.price}/${t("certd.vip.years")}`,
|
||||
discountText: props.productInfo.comm.discountText || `¥${props.productInfo.comm.price3}/3${t("certd.vip.years")}`,
|
||||
tooltip: props.productInfo.comm.tooltip,
|
||||
trial: {
|
||||
title: t("vip.click_to_get_7_day_trial"),
|
||||
title: t("certd.vip.click_to_get_7_day_trial"),
|
||||
click: () => {
|
||||
props.openStarModal("comm");
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<script lang="ts" setup>
|
||||
<script lang="ts" setup>
|
||||
import { BasicLayout, LockScreen, UserDropdown } from "/@/vben/layouts";
|
||||
|
||||
import { computed, onErrorCaptured, onMounted, provide, ref } from "vue";
|
||||
@@ -23,14 +23,14 @@ const menus = computed(() => [
|
||||
router.push("/cert/mine/user-profile");
|
||||
},
|
||||
icon: "fa-solid:book",
|
||||
text: t("certd.accountInfo"),
|
||||
text: t("certd.mine.accountInfo"),
|
||||
},
|
||||
{
|
||||
handler: () => {
|
||||
router.push("/cert/mine/security");
|
||||
},
|
||||
icon: "fluent:shield-keyhole-16-regular",
|
||||
text: t("certd.securitySettings"),
|
||||
text: t("certd.mine.securitySettings"),
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -109,7 +109,7 @@ const projectStore = useProjectStore();
|
||||
<vip-button class="flex-center header-btn" mode="nav" />
|
||||
</div>
|
||||
<div v-if="!settingStore.isComm" class="hover:bg-accent ml-1 mr-2 cursor-pointer rounded-full hidden md:block">
|
||||
<fs-button shape="circle" type="text" icon="clarity:host-solid-badged" :text="null" :tooltip="{ title: t('certd.client') }" @click="goCertdClient" />
|
||||
<fs-button shape="circle" type="text" icon="clarity:host-solid-badged" :text="null" :tooltip="{ title: t('certd.navigation.client') }" @click="goCertdClient" />
|
||||
</div>
|
||||
<div v-if="!settingStore.isComm" class="hover:bg-accent ml-1 mr-2 cursor-pointer rounded-full hidden md:block">
|
||||
<fs-button shape="circle" type="text" icon="ion:logo-github" :text="null" @click="goGithub" />
|
||||
|
||||
@@ -13,34 +13,54 @@ import notification from "./certd/notification";
|
||||
import addon from "./certd/addon";
|
||||
import suite from "./certd/suite";
|
||||
import project from "./certd/project";
|
||||
import syssettings from "./certd/sys-settings";
|
||||
import sysplugin from "./certd/sys-plugin";
|
||||
import sysauthority from "./certd/sys-authority";
|
||||
import syscname from "./certd/sys-cname";
|
||||
import settings from "./certd/sys-settings";
|
||||
import plugin from "./certd/sys-plugin";
|
||||
import authority from "./certd/sys-authority";
|
||||
import cnameSettings from "./certd/sys-cname";
|
||||
import tutorial from "./certd/tutorial";
|
||||
import cron from "./certd/cron";
|
||||
import client from "./certd/client";
|
||||
import wallet from "./certd/wallet";
|
||||
import nettest from "./certd/nettest";
|
||||
import audit from "./certd/audit";
|
||||
import applyTemplate from "./certd/apply-template";
|
||||
import dnsPersist from "./certd/dns-persist";
|
||||
import auth from "./certd/auth";
|
||||
import guide from "./certd/guide";
|
||||
import vip from "./certd/vip";
|
||||
|
||||
// Note: @ is reserved in locale messages; use {'@'} when needed.
|
||||
export default {
|
||||
...common,
|
||||
...navigation,
|
||||
...dashboard,
|
||||
...pipeline,
|
||||
...history,
|
||||
...monitor,
|
||||
...certdomain,
|
||||
...cname,
|
||||
...access,
|
||||
...open,
|
||||
...mine,
|
||||
...notification,
|
||||
...addon,
|
||||
...suite,
|
||||
...project,
|
||||
...syssettings,
|
||||
...sysplugin,
|
||||
...sysauthority,
|
||||
...syscname,
|
||||
...tutorial,
|
||||
...cron,
|
||||
common,
|
||||
navigation,
|
||||
dashboard,
|
||||
pipeline,
|
||||
history,
|
||||
monitor,
|
||||
certdomain,
|
||||
cname,
|
||||
access,
|
||||
open,
|
||||
mine,
|
||||
notification,
|
||||
addon,
|
||||
suite,
|
||||
project,
|
||||
sys: {
|
||||
settings,
|
||||
plugin,
|
||||
authority,
|
||||
cname: cnameSettings,
|
||||
},
|
||||
tutorial,
|
||||
cron,
|
||||
client,
|
||||
wallet,
|
||||
nettest,
|
||||
audit,
|
||||
applyTemplate,
|
||||
dnsPersist,
|
||||
auth,
|
||||
guide,
|
||||
vip,
|
||||
};
|
||||
|
||||
@@ -4,4 +4,11 @@ export default {
|
||||
nameHelper: "Fill in as you like, useful to distinguish when multiple authorizations of the same type exist",
|
||||
level: "Level",
|
||||
system: "System",
|
||||
select: "Select",
|
||||
selectProvider: "Select Authorization Provider",
|
||||
deleteConfirm: "If this authorization is already in use, pipelines may fail. Proceed with caution.",
|
||||
name: "Name",
|
||||
user: "User",
|
||||
type: "Type",
|
||||
selectType: "Please select a type",
|
||||
};
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export default {
|
||||
setSuccess: "Settings saved",
|
||||
editTitle: "Edit Certificate Application Template",
|
||||
addTitle: "Add Certificate Application Template",
|
||||
name: "Template Name",
|
||||
default: "Default",
|
||||
setDefault: "Set as Default",
|
||||
disabled: "Disabled",
|
||||
createTime: "Created At",
|
||||
config: "Configuration",
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
export default {
|
||||
createTime: "Operation Time",
|
||||
type: "Operation Type",
|
||||
action: "Action",
|
||||
result: "Result",
|
||||
success: "Success",
|
||||
failed: "Failed",
|
||||
remark: "Remark",
|
||||
ipAddress: "IP Address",
|
||||
};
|
||||
+26
-54
@@ -1,58 +1,4 @@
|
||||
export default {
|
||||
welcomeBack: "Welcome Back",
|
||||
pageTitle: "Plug-and-play Admin system",
|
||||
pageDesc: "Efficient, versatile frontend template",
|
||||
loginSuccess: "Login Successful",
|
||||
loginSuccessDesc: "Welcome Back",
|
||||
loginSubtitle: "Enter your account details to manage your projects",
|
||||
selectAccount: "Quick Select Account",
|
||||
username: "Username",
|
||||
password: "Password",
|
||||
usernameTip: "Please enter username",
|
||||
passwordErrorTip: "Password is incorrect",
|
||||
passwordTip: "Please enter password",
|
||||
verifyRequiredTip: "Please complete the verification first",
|
||||
rememberMe: "Remember Me",
|
||||
createAnAccount: "Create an Account",
|
||||
createAccount: "Create Account",
|
||||
alreadyHaveAccount: "Already have an account?",
|
||||
accountTip: "Don't have an account?",
|
||||
signUp: "Sign Up",
|
||||
signUpSubtitle: "Make managing your applications simple and fun",
|
||||
confirmPassword: "Confirm Password",
|
||||
confirmPasswordTip: "The passwords do not match",
|
||||
agree: "I agree to",
|
||||
privacyPolicy: "Privacy-policy",
|
||||
terms: "Terms",
|
||||
agreeTip: "Please agree to the Privacy Policy and Terms",
|
||||
goToLogin: "Login instead",
|
||||
passwordStrength: "Use 8 or more characters with a mix of letters, numbers & symbols",
|
||||
forgetPassword: "Forget Password?",
|
||||
forgetPasswordSubtitle: "Enter your email and we'll send you instructions to reset your password",
|
||||
emailTip: "Please enter email",
|
||||
emailValidErrorTip: "The email format you entered is incorrect",
|
||||
sendResetLink: "Send Reset Link",
|
||||
email: "Email",
|
||||
qrcodeSubtitle: "Scan the QR code with your phone to login",
|
||||
qrcodePrompt: "Click 'Confirm' after scanning to complete login",
|
||||
qrcodeLogin: "QR Code Login",
|
||||
codeSubtitle: "Enter your phone number to start managing your project",
|
||||
code: "Security code",
|
||||
codeTip: "Security code required {0} characters",
|
||||
mobile: "Mobile",
|
||||
mobileLogin: "Mobile Login",
|
||||
mobileTip: "Please enter mobile number",
|
||||
mobileErrortip: "The phone number format is incorrect",
|
||||
sendCode: "Get Security code",
|
||||
sendText: "Resend in {0}s",
|
||||
thirdPartyLogin: "Or continue with",
|
||||
loginAgainTitle: "Please Log In Again",
|
||||
loginAgainSubTitle: "Your login session has expired. Please log in again to continue.",
|
||||
layout: {
|
||||
center: "Align Center",
|
||||
alignLeft: "Align Left",
|
||||
alignRight: "Align Right",
|
||||
},
|
||||
loginType: {
|
||||
password: "Password Login",
|
||||
sms: "Mobile Login",
|
||||
@@ -110,4 +56,30 @@ export default {
|
||||
userInfo: "User Info",
|
||||
securitySettingTip: "2FA Setting",
|
||||
securitySetting: "2FA Setting",
|
||||
register: {
|
||||
usernameTab: "Register with username",
|
||||
emailTab: "Register with email",
|
||||
mobileTab: "Register with mobile",
|
||||
username: "Username",
|
||||
email: "Email",
|
||||
password: "Password",
|
||||
confirmPassword: "Confirm Password",
|
||||
captcha: "Captcha",
|
||||
emailCode: "Email verification code",
|
||||
mobileLogin: "Go to mobile login (login to register)",
|
||||
inviteCode: "Invitation code",
|
||||
inviteCodeOptional: "Invitation code (optional)",
|
||||
submit: "Register",
|
||||
login: "Log In",
|
||||
noMethodEnabled: "No registration method is enabled",
|
||||
usernameRequired: "Please enter your username",
|
||||
emailRequired: "Please enter your email",
|
||||
emailInvalid: "Please enter a valid email address",
|
||||
passwordRequired: "Please enter your password",
|
||||
confirmPasswordRequired: "Please confirm your password",
|
||||
passwordMismatch: "The two passwords do not match",
|
||||
smsCodeRequired: "Please enter the SMS verification code",
|
||||
emailCodeRequired: "Please enter the email verification code",
|
||||
captchaRequired: "Please complete the captcha",
|
||||
},
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
export default {
|
||||
domain: {
|
||||
dnsPersistDescription: "Currently, only Google certificates support DNS persistent validation.",
|
||||
domainManager: "Domain Manager",
|
||||
domainDescription: "used to auto apply for certificate", //管理域名的校验方式,用于申请证书时自动选择验证方式
|
||||
domain: "Domain",
|
||||
@@ -19,6 +20,7 @@ export default {
|
||||
subdomainConfirmContent: "{domain} appears to be a subdomain. Only delegated subdomains and free second-level subdomains need to be maintained here. Otherwise certificate application may fail. Continue?",
|
||||
importFromProvider: "Import from Domain Provider",
|
||||
importFromResolveRecords: "Import from DNS Records",
|
||||
importFromResolveRecordsTooltip: "Import DNS records as monitoring sites",
|
||||
syncExpirationDate: "Sync Domain Expiration Time",
|
||||
syncTaskSubmitted: "Sync task submitted",
|
||||
syncExpirationProgress: "Sync Domain Expiration Progress",
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
export default {
|
||||
clientManager: "Client Manager",
|
||||
title: "Client Manager",
|
||||
description: "View online status and managed site count of connected Certd clients. Clients report a heartbeat every 10 minutes and are marked offline if no heartbeat arrives for 30 minutes.",
|
||||
plusRequired: "This feature requires the Pro edition",
|
||||
machineName: "Machine",
|
||||
clientId: "Client ID",
|
||||
version: "Version",
|
||||
os: "OS",
|
||||
status: "Status",
|
||||
online: "Online",
|
||||
offline: "Offline",
|
||||
siteCount: "Sites",
|
||||
httpsSiteCount: "HTTPS Sites",
|
||||
syncedSiteCount: "Synced",
|
||||
failedSiteCount: "Failed",
|
||||
lastHeartbeatAt: "Last Heartbeat",
|
||||
};
|
||||
@@ -1,4 +1,6 @@
|
||||
export default {
|
||||
required: "Required",
|
||||
no: "No",
|
||||
usera: "User",
|
||||
disabledSuccess: "Disabled successfully",
|
||||
app: {
|
||||
@@ -21,12 +23,18 @@ export default {
|
||||
add: "Generate New Key",
|
||||
edit: "Edit",
|
||||
deleteSuccess: "Delete successful",
|
||||
fastCrud: {
|
||||
view: "View",
|
||||
copy: "Copy",
|
||||
edit: "Edit",
|
||||
remove: "Delete",
|
||||
addSuccess: "Added successfully",
|
||||
saveSuccess: "Saved successfully",
|
||||
},
|
||||
saveSuccess: "Saved successfully",
|
||||
cancel: "Cancel",
|
||||
yes: "Yes",
|
||||
no: "No",
|
||||
all: "All",
|
||||
required: "This field is required",
|
||||
requiredField: "This field is required",
|
||||
fieldRequired: "This field is required",
|
||||
field_required: "This field is required",
|
||||
|
||||
@@ -1,50 +1,59 @@
|
||||
export default {
|
||||
dashboard: {
|
||||
greeting: "Hello, {name}, welcome to 【{site}】",
|
||||
latestVersion: "Latest version: {version}",
|
||||
validUntil: "Valid until:",
|
||||
tutorialTooltip: "Click to view detailed tutorial",
|
||||
tutorialText: "Only 3 steps to automatically apply and deploy certificates",
|
||||
alertMessage: "Certificates and credentials are sensitive. Do not use untrusted online Certd services or images. Always self-host and use official release channels:",
|
||||
helpDoc: "Help Docs",
|
||||
pipelineCount: "Number of Certificate Pipelines",
|
||||
noPipeline: "You have no certificate pipelines yet",
|
||||
enabledCount: "Enabled",
|
||||
disabledCount: "Disabled",
|
||||
certCount: "Number of Certificates",
|
||||
noCert: "You have no certificates yet",
|
||||
manageCert: "View Certificates",
|
||||
siteMonitorCount: "Number of Monitored Sites",
|
||||
siteAbnormalCount: "Abnormal",
|
||||
siteNormalCount: "Normal",
|
||||
manageSiteMonitor: "Manage Monitored Sites",
|
||||
domainCount: "Number of Domains",
|
||||
domainExpiringCount: "Expiring",
|
||||
domainExpiredCount: "Expired",
|
||||
domainNotExpiredCount: "Not Expired",
|
||||
manageDomain: "Manage Domains",
|
||||
certExpiringCount: "Soon-to-Expire",
|
||||
certExpiredCount: "Expired",
|
||||
certNoExpireCount: "Not Expired",
|
||||
createNow: "Create Now",
|
||||
managePipeline: "Manage Pipelines",
|
||||
pipelineStatus: "Pipeline Status",
|
||||
recentRun: "Recent Run Statistics",
|
||||
runCount: "Run Count",
|
||||
expiringCerts: "Soon-to-Expire Certificates",
|
||||
totalGeneratedCertCount: "Total Certificates Generated",
|
||||
singleDomainCertShortCount: "Single-domain",
|
||||
multiDomainCertShortCount: "Multi-domain",
|
||||
wildcardCertShortCount: "Wildcard",
|
||||
singleDomainCertCount: "Single-domain Certificates Generated",
|
||||
multiDomainCertCount: "Multi-domain Certificates Generated",
|
||||
wildcardCertCount: "Wildcard Certificates Generated",
|
||||
savedAmount: "Estimated savings",
|
||||
savedAmountRule: "Estimated at one quarter of Tencent Cloud's annual certificate prices: single-domain ¥532, multi-domain ¥912, and wildcard ¥2147. Actual savings may vary.",
|
||||
totalPipelineRuns: "Total Pipeline Runs",
|
||||
supportedTasks: "Overview of Supported Deployment Tasks",
|
||||
changeLog: "Change Log",
|
||||
stableRelease: "Stable",
|
||||
latestRelease: "Preview",
|
||||
},
|
||||
greeting: "Hello, {name}, welcome to 【{site}】",
|
||||
latestVersion: "Latest version: {version}",
|
||||
validUntil: "Valid until:",
|
||||
tutorialTooltip: "Click to view detailed tutorial",
|
||||
tutorialText: "Only 3 steps to automatically apply and deploy certificates",
|
||||
alertMessage: "Certificates and credentials are sensitive. Do not use untrusted online Certd services or images. Always self-host and use official release channels:",
|
||||
helpDoc: "Help Docs",
|
||||
pipelineCount: "Number of Certificate Pipelines",
|
||||
noPipeline: "You have no certificate pipelines yet",
|
||||
enabledCount: "Enabled",
|
||||
disabledCount: "Disabled",
|
||||
certCount: "Number of Certificates",
|
||||
noCert: "You have no certificates yet",
|
||||
manageCert: "View Certificates",
|
||||
siteMonitorCount: "Number of Monitored Sites",
|
||||
siteAbnormalCount: "Abnormal",
|
||||
siteNormalCount: "Normal",
|
||||
manageSiteMonitor: "Manage Monitored Sites",
|
||||
domainCount: "Number of Domains",
|
||||
domainExpiringCount: "Expiring",
|
||||
domainExpiredCount: "Expired",
|
||||
domainNotExpiredCount: "Not Expired",
|
||||
manageDomain: "Manage Domains",
|
||||
certExpiringCount: "Soon-to-Expire",
|
||||
certExpiredCount: "Expired",
|
||||
certNoExpireCount: "Not Expired",
|
||||
createNow: "Create Now",
|
||||
managePipeline: "Manage Pipelines",
|
||||
pipelineStatus: "Pipeline Status",
|
||||
recentRun: "Recent Run Statistics",
|
||||
runCount: "Run Count",
|
||||
expiringCerts: "Soon-to-Expire Certificates",
|
||||
totalGeneratedCertCount: "Total Certificates Generated",
|
||||
singleDomainCertShortCount: "Single-domain",
|
||||
multiDomainCertShortCount: "Multi-domain",
|
||||
wildcardCertShortCount: "Wildcard",
|
||||
singleDomainCertCount: "Single-domain Certificates Generated",
|
||||
multiDomainCertCount: "Multi-domain Certificates Generated",
|
||||
wildcardCertCount: "Wildcard Certificates Generated",
|
||||
savedAmount: "Estimated savings",
|
||||
savedAmountRule: "Estimated at one quarter of Tencent Cloud's annual certificate prices: single-domain ¥532, multi-domain ¥912, and wildcard ¥2147. Actual savings may vary.",
|
||||
totalPipelineRuns: "Total Pipeline Runs",
|
||||
supportedTasks: "Overview of Supported Deployment Tasks",
|
||||
supportedTasksHelper: "This list is for display only. Create a pipeline to use these tasks.",
|
||||
changeLog: "Change Log",
|
||||
stableRelease: "Stable",
|
||||
latestRelease: "Preview",
|
||||
consoleTitle: "Console",
|
||||
userTotal: "Total Users",
|
||||
manageUsers: "Manage Users",
|
||||
userGrowth: "User Growth",
|
||||
newUsers: "New Users",
|
||||
allPipelineTotal: "Total Pipelines",
|
||||
managePipelines: "Manage Pipelines",
|
||||
pipelineGrowth: "Pipeline Growth",
|
||||
newPipelines: "New Pipelines",
|
||||
recentRunTitle: "Recent Run Statistics",
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
export default {
|
||||
pending: "Pending Setup",
|
||||
created: "Created",
|
||||
validating: "Validating",
|
||||
valid: "Valid",
|
||||
retry: "Retry",
|
||||
deleteTxtTip: "Delete the TXT record at the provider",
|
||||
accountUriMissing: "The ACME account authorization is missing accountUri. Please regenerate the account.",
|
||||
verifySuccess: "Validation succeeded",
|
||||
verifyFailed: "No matching TXT record found. Please try again later.",
|
||||
submitted: "Validation submitted",
|
||||
selectProviderAndAccess: "Select a DNS provider and authorization",
|
||||
txtCreated: "TXT record created",
|
||||
settingTitle: "Set DNS TXT Record",
|
||||
manualAdd: "Add Manually",
|
||||
autoAdd: "Add with Authorization",
|
||||
manualTip: "Add the following TXT record in your DNS console, then click OK to validate immediately.",
|
||||
autoTip: "Select a DNS provider and authorization. The system will create the TXT record and validate it in the background.",
|
||||
mainDomain: "Main Domain",
|
||||
txtHost: "TXT Host",
|
||||
txtValue: "TXT Value",
|
||||
provider: "DNS Provider",
|
||||
access: "DNS Authorization",
|
||||
};
|
||||
+2
@@ -7,6 +7,8 @@ export default {
|
||||
settingLink: "Site Monitoring Settings",
|
||||
limitInfo: "Basic edition limited to 1, professional and above unlimited, current",
|
||||
checkAll: "Check All",
|
||||
checkBatch: "Check Selected",
|
||||
batchCheckConfirm: "Check the {count} selected sites now?",
|
||||
checkNow: "Check Now",
|
||||
batchDelete: "Batch Delete",
|
||||
confirmTitle: "Confirm",
|
||||
@@ -1,4 +1,7 @@
|
||||
import monitorSite from "./monitor-site";
|
||||
|
||||
export default {
|
||||
...monitorSite,
|
||||
certificateRepo: {
|
||||
title: "Certificate Repository",
|
||||
sub: "Certificates generated from pipeline",
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
export default {
|
||||
home: "Home",
|
||||
login: "Login",
|
||||
register: "Register",
|
||||
forgotPassword: "Forgot Password",
|
||||
oauthCallback: "OAuth Callback",
|
||||
framework: {
|
||||
title: "Framework",
|
||||
home: "Home",
|
||||
@@ -13,10 +18,13 @@ export default {
|
||||
accessManager: "Access Management",
|
||||
dnsPersistRecord: "DNS Persist Records",
|
||||
certApplyTemplate: "Certificate Apply Templates",
|
||||
certApplyTemplateHelper: "Preset certificate application parameters. They are filled automatically when creating a pipeline (excluding domains and validation methods).",
|
||||
subDomain: "Subdomain Delegation Settings",
|
||||
pipelineGroup: "Pipeline Group Management",
|
||||
pipelineGroupHelper: "Manage pipeline groups",
|
||||
openKey: "Open API Key",
|
||||
notification: "Notification Settings",
|
||||
notificationHelper: "Manage notification configurations",
|
||||
siteMonitorSetting: "Site Monitor Settings",
|
||||
auditLog: "Audit Log",
|
||||
userSecurity: "Security Settings",
|
||||
@@ -25,6 +33,7 @@ export default {
|
||||
mySuite: "My Suite",
|
||||
suiteBuy: "Suite Purchase",
|
||||
myTrade: "My Orders",
|
||||
myWallet: "My Wallet",
|
||||
inviteCommission: "Incentive Plan",
|
||||
paymentReturn: "Payment Return",
|
||||
client: "Certd Client",
|
||||
@@ -48,7 +57,9 @@ export default {
|
||||
userManager: "User Management",
|
||||
userDataManager: "User Data Management",
|
||||
pipelineManager: "User Pipeline Management",
|
||||
pipelineManagerHelper: "Manage all users' pipelines",
|
||||
siteMonitorManager: "User Certificate Monitor",
|
||||
siteMonitorManagerHelper: "Manage all users' certificate monitors",
|
||||
suiteManager: "Suite Management",
|
||||
suiteSetting: "Suite Settings",
|
||||
orderManager: "Order Management",
|
||||
@@ -72,6 +83,8 @@ export default {
|
||||
currentProject: "Current Project",
|
||||
projectMemberManager: "Project Member",
|
||||
auditLog: "Audit Log",
|
||||
auditLogHelper: "View all users' operation records",
|
||||
jobHistory: "Monitoring Execution History",
|
||||
domainMonitorSetting: "Domain Monitor Settings",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
export default {
|
||||
title: "Network Test",
|
||||
helper: "Test whether your server container network is working",
|
||||
customDomain: "Custom Domain Test",
|
||||
serverInfo: "Server Information",
|
||||
refresh: "Refresh",
|
||||
loading: "Loading...",
|
||||
fetchFailed: "Failed to fetch server information",
|
||||
noInfo: "No information",
|
||||
localIp: "Local IP",
|
||||
publicIp: "Public IP",
|
||||
dnsServer: "DNS Server",
|
||||
};
|
||||
@@ -3,6 +3,13 @@ export default {
|
||||
scopeOpenApiOnly: "Open API Only",
|
||||
scopeFullAccount: "Full Account Permissions",
|
||||
scopeHelper: "Open API only allows access to open APIs; full account permissions allow access to all APIs",
|
||||
keyRemark: "Key Purpose",
|
||||
keyRemarkHelper: "Describe the purpose of this key for easier identification",
|
||||
keyRemarkMaxChars: "Maximum 512 characters",
|
||||
returnCertPassword: "Return certificate password",
|
||||
returnCertPasswordHelper: "When enabled, the certificate password is included in Open API certificate responses. Keep this key secure.",
|
||||
yes: "Yes",
|
||||
no: "No",
|
||||
gen: {
|
||||
text: "API Test",
|
||||
title: "x-certd-token",
|
||||
|
||||
@@ -33,6 +33,10 @@ export default {
|
||||
pipelineStarted: "Pipeline has started running",
|
||||
},
|
||||
actions: {
|
||||
edit: "Edit",
|
||||
delete: "Delete",
|
||||
enable: "Enable",
|
||||
disable: "Disable",
|
||||
editPipeline: "Edit Pipeline",
|
||||
editConfigGroup: "Modify Configuration/Group",
|
||||
viewCertificate: "View Certificate",
|
||||
@@ -65,6 +69,145 @@ export default {
|
||||
legoAcme: "Lego-ACME: Based on Lego, supports a wide range of DNS providers, suitable for users familiar with Lego",
|
||||
aliyunOrder: "Aliyun-Order: Get certificate from Aliyun certificate order",
|
||||
},
|
||||
editor: {
|
||||
editTask: "Edit Task",
|
||||
editStep: "Edit Step",
|
||||
installedPlugins: "Installed Plugins",
|
||||
pluginMarket: "Plugin Market",
|
||||
searchPluginMarket: "Search plugin market",
|
||||
searchLocalPlugins: "Search local plugins",
|
||||
loadingPluginMarket: "Loading plugin market...",
|
||||
noPluginFound: "No plugins found",
|
||||
triggerManually: "Trigger Manually",
|
||||
triggerSource: "Trigger Source",
|
||||
scheduledTrigger: "Trigger Source (Scheduled)",
|
||||
webhookTrigger: "Trigger Source (Webhook)",
|
||||
certExpireTime: "Certificate expiration time: ",
|
||||
certExpired: "Certificate expired ",
|
||||
viewCertificate: "View Certificate",
|
||||
downloadCertificate: "Download Certificate",
|
||||
nextExecutionTime: "Next execution time: ",
|
||||
noTriggerSource: "No trigger source configured; it will not run automatically",
|
||||
validityPeriod: "Validity period: ",
|
||||
save: "Save",
|
||||
cancel: "Cancel",
|
||||
addStage: "New Stage",
|
||||
addTask: "Add Task",
|
||||
addAfterTask: "Add After-Task",
|
||||
addNotification: "Add Notification",
|
||||
notificationNotSet: "Notification not set",
|
||||
history: "Execution History",
|
||||
historyHint: "Click a task to view logs",
|
||||
taskName: "Task Name",
|
||||
taskSteps: "Task Steps",
|
||||
addStep: "Add Step",
|
||||
copy: "Copy",
|
||||
paste: "Paste",
|
||||
confirm: "Confirm",
|
||||
required: "This field is required",
|
||||
taskNeedsStep: "At least one step is required, or delete this task using the button beside the title",
|
||||
step: "Step",
|
||||
endStage: "End",
|
||||
confirmTitle: "Confirm",
|
||||
confirmManualRun: "Are you sure you want to trigger the run manually?",
|
||||
taskLog: "Task Log",
|
||||
noLogs: "No logs (this node was not triggered or has no log records for this run)",
|
||||
aiAnalyze: "AI Analysis",
|
||||
rerun: "Rerun",
|
||||
downloadLogs: "Download Logs",
|
||||
close: "Close",
|
||||
batchEditSteps: "Batch Edit Steps",
|
||||
selectAllSteps: "Select All Steps",
|
||||
batchEnableSteps: "Batch Enable Steps",
|
||||
batchDisableSteps: "Batch Disable Steps",
|
||||
batchDeleteSteps: "Batch Delete Steps",
|
||||
exitBatchEdit: "Exit Batch Edit",
|
||||
stepsSerialHelper: "Steps run sequentially. If an earlier step fails, later steps will not run.",
|
||||
current: "Current",
|
||||
view: "View",
|
||||
confirmCancel: "Confirm Cancellation",
|
||||
confirmCancelTask: "Cancel this task?",
|
||||
taskCanceled: "Task canceled successfully",
|
||||
selectAllTasks: "Select all tasks",
|
||||
batchEnableTasks: "Enable tasks in batch",
|
||||
batchDisableTasks: "Disable tasks in batch",
|
||||
batchDeleteTasks: "Delete tasks in batch",
|
||||
exitBatchEditTasks: "Exit batch edit",
|
||||
editStageTitle: "Edit stage title",
|
||||
batchEditTasks: "Edit tasks in batch",
|
||||
dragSort: "Drag to reorder",
|
||||
forceRerun: "Force rerun this step",
|
||||
resizeStage: "Drag to resize stage",
|
||||
afterLabel: "After-task",
|
||||
notificationLabel: "Notification",
|
||||
unsavedLeave: "This pipeline is not saved. Leave anyway?",
|
||||
newPipeline: "New Pipeline",
|
||||
newTask: "New Task",
|
||||
newStage: "New Stage",
|
||||
stageSuffix: " Stage",
|
||||
saveBeforeRunTitle: "Save before running the pipeline",
|
||||
saveBeforeRunContent: "Save it first?",
|
||||
runUnsupported: "Running is not supported yet",
|
||||
addStageAndTask: "Please add a stage and task first",
|
||||
prerequisiteMissing: "The prerequisite output step {param} for {step} does not exist or is disabled",
|
||||
selectPlugin: "Select plugin",
|
||||
searchPlugin: "Search plugins",
|
||||
searchResults: "Search results",
|
||||
plusPluginRequired: "This plugin requires Certd Professional",
|
||||
immediateRun: "Run immediately",
|
||||
immediateRunHelper: "Run the pipeline immediately after saving",
|
||||
operationSuccess: "Operation successful",
|
||||
regenerate: "Regenerate",
|
||||
webhookHelper: "Supports POST and GET requests (each pipeline has a unique Webhook URL)",
|
||||
regenerateWebhookTitle: "Regenerate the Webhook URL?",
|
||||
regenerateWebhookContent: "The old Webhook URL will become invalid",
|
||||
confirmDeleteTask: "Delete this task?",
|
||||
confirmDeleteStep: "Delete this step?",
|
||||
confirmDeleteSelectedTasks: "Delete the selected {count} tasks?",
|
||||
confirmDeleteSelectedSteps: "Delete the selected {count} steps?",
|
||||
stepCopied: "Step configuration copied. You can paste it in another task editor",
|
||||
allStepsCopied: "All steps copied. You can paste them in another task editor",
|
||||
copyFirst: "Please copy first",
|
||||
pasted: "Pasted successfully",
|
||||
enterName: "Please enter a name",
|
||||
pluginTypeFirst: "Please select a type first",
|
||||
runStrategy: "Run strategy",
|
||||
runStrategyNormal: "Run normally (required for certificate tasks unless you want this task to run every time)",
|
||||
runStrategySkip: "Skip after success (choose this for other tasks)",
|
||||
runStrategyDefault: "Usually keep the default",
|
||||
runStrategyNormalHelp: "Run normally: runs every time; certificate tasks need this",
|
||||
runStrategySkipHelp: "Skip after success: skip after one successful run and run again when the certificate changes",
|
||||
triggerWebhook: "Webhook Trigger",
|
||||
triggerSchedule: "Scheduled Trigger",
|
||||
choose: "Select",
|
||||
noLogsShort: "No logs",
|
||||
statusSuccess: "success",
|
||||
statusError: "error",
|
||||
statusSkip: "skip",
|
||||
statusStart: "running",
|
||||
statusCanceled: "canceled",
|
||||
statusNone: "not run",
|
||||
statusDisabled: "disabled",
|
||||
statusNoDeployCount: "insufficient runs",
|
||||
pluginGroups: {
|
||||
all: "All",
|
||||
cert: "Certificate",
|
||||
host: "Host",
|
||||
cdn: "CDN",
|
||||
panel: "Panel",
|
||||
aliyun: "Alibaba Cloud",
|
||||
huawei: "Huawei Cloud",
|
||||
tencent: "Tencent Cloud",
|
||||
volcengine: "Volcengine",
|
||||
jdcloud: "JD Cloud",
|
||||
ucloud: "UCloud",
|
||||
baidu: "Baidu Cloud",
|
||||
qiniu: "Qiniu Cloud",
|
||||
aws: "Amazon Web Services",
|
||||
other: "Other",
|
||||
admin: "Administration",
|
||||
},
|
||||
},
|
||||
pipelineForm: {
|
||||
createTitle: "Create Certificate Pipeline",
|
||||
moreParams: "More Parameters",
|
||||
|
||||
@@ -1,4 +1,50 @@
|
||||
export default {
|
||||
title: "Suite",
|
||||
mySuite: "My Suite",
|
||||
suiteBuy: "Suite Purchase",
|
||||
myTrade: "My Orders",
|
||||
inviteCommission: "Incentive Plan",
|
||||
inviteSubtitle: "Invite friends and earn generous commissions",
|
||||
promotionAgreement: "Promotion Agreement",
|
||||
withdraw: "Withdraw",
|
||||
withdrawAvailable: "Available to withdraw {amount}",
|
||||
inviteCode: "Invitation Code",
|
||||
orderTime: "Time",
|
||||
inviteTime: "Invitation Time",
|
||||
inviteeUsername: "Invited Username",
|
||||
inviteLink: "Invitation Link",
|
||||
myLevel: "My Level",
|
||||
unset: "Not set",
|
||||
commissionRate: "Commission Rate",
|
||||
commissionAfterPayment: "Commission is calculated at this rate after a friend pays",
|
||||
proportion: "Rate",
|
||||
inviteSuccess: "Successful Invites",
|
||||
incomeRecords: "Income Records",
|
||||
enableFirst: "Please enable the incentive plan first",
|
||||
enable: "Enable Incentive Plan",
|
||||
disabled: "Incentive plan is not enabled",
|
||||
totalIncome: "Total Income",
|
||||
monthIncome: "This Month's Income",
|
||||
promotionAmount: "Total Promotion Amount",
|
||||
inviteeCount: "People Invited",
|
||||
people: " people",
|
||||
agreePromotion: "I have read and agree to the promotion agreement",
|
||||
close: "Close",
|
||||
postpone: "Later",
|
||||
agreeAndEnable: "Agree and Enable",
|
||||
agreeRequired: "Please check the agreement first",
|
||||
enabledSuccess: "Incentive plan enabled",
|
||||
purchaseSuccess: "Suite purchased successfully",
|
||||
agreementPlaceholder: "Enter the promotion agreement users must accept before enabling the incentive plan",
|
||||
activationExchange: "Redeem Activation Code",
|
||||
activationCode: "Activation Code",
|
||||
enterActivationCode: "Please enter the activation code",
|
||||
enterCdkCode: "Please enter the CDK activation code",
|
||||
activateSuccess: "Activated successfully",
|
||||
exchangeFailed: "Redemption failed",
|
||||
noSuite: "No suites available for purchase",
|
||||
suiteHelperStack: "Note: Multiple suites and addons can be purchased, and their quantities are accumulated",
|
||||
suiteHelperLatest: "Note: 1) Only the latest suite is active at a time; 2) Multiple addons can be purchased and take effect immediately; 3) Suite and addon quantities are accumulated",
|
||||
order: {
|
||||
confirmTitle: "Order Confirmation",
|
||||
package: "Package",
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
export default {
|
||||
aiDevTitle: "AI Plugin Development",
|
||||
certPluginConfig: "Certificate Plugin Configuration",
|
||||
saveSuccess: "Saved successfully",
|
||||
commonGoogleAcme: "Common Google ACME Account",
|
||||
commonZeroSslAcme: "Common ZeroSSL ACME Account",
|
||||
commonLiteSslAcme: "Common LiteSSL ACME Account",
|
||||
otherConfig: "Other Configuration",
|
||||
certApplyDefaults: "Certificate Apply Plugin Defaults",
|
||||
customCertApplyParams: "Custom certificate application plugin parameters",
|
||||
save: "Save",
|
||||
titlea: "Title",
|
||||
pluginFile: "Plugin File",
|
||||
selectPluginFile: "Select plugin file",
|
||||
|
||||
@@ -1,118 +1,134 @@
|
||||
export default {
|
||||
sys: {
|
||||
setting: {
|
||||
baseSetting: "Base Settings",
|
||||
registerSetting: "Register Settings",
|
||||
safeSetting: "Safe Settings",
|
||||
paymentSetting: "Payment Settings",
|
||||
captchaSetting: "Captcha Setting",
|
||||
pipelineSetting: "Pipeline Settings",
|
||||
oauthSetting: "Login Settings",
|
||||
networkSetting: "Network Settings",
|
||||
adminModeSetting: "Admin Mode Settings",
|
||||
adminModeHelper: "enterprise mode : allow to create and manage pipelines, roles, users, etc.\n saas mode : only allow to create and manage pipelines",
|
||||
enterpriseMode: "Enterprise Mode",
|
||||
saasMode: "SaaS Mode",
|
||||
modeIntroTitle: "Management Mode Introduction",
|
||||
saasModeDescription: "SaaS mode: each user manages and independently uses their own pipelines and authorization resources.",
|
||||
enterpriseModeDescription: "Enterprise mode: pipelines, certificates, and authorization resources are managed through projects for all internal users.",
|
||||
switchModeNow: "Switch Mode Now",
|
||||
suiteSetting: "Suite Settings",
|
||||
orderManager: "Order Management",
|
||||
headerMenuSetting: "Top Menu Settings",
|
||||
sitePersonalization: "Site Personalization",
|
||||
siteName: "Site Name",
|
||||
slogan: "Subtitle / Slogan",
|
||||
loginLogo: "Login Page Logo",
|
||||
entityName: "Entity Name",
|
||||
shownAtBottom: "Displayed at the bottom",
|
||||
entityUrl: "Entity URL",
|
||||
modeSaasHelper: "SaaS mode: each user manages and independently uses their own pipelines and authorization resources.",
|
||||
modeEnterpriseHelper: "Enterprise mode: pipelines, certificates, and authorization resources are managed through projects for all internal users.",
|
||||
modeMore: "More Management Mode Details",
|
||||
modeFixedWarning: "Choose a suitable mode before use and avoid switching it frequently afterwards.",
|
||||
modeMigrate: "After switching to enterprise mode, personal data created earlier will be hidden. You can migrate it to a project.",
|
||||
modeCommWarning: "Enterprise mode is not recommended for the commercial edition unless you intend to use it internally.",
|
||||
baseSetting: "Base Settings",
|
||||
registerSetting: "Register Settings",
|
||||
safeSetting: "Safe Settings",
|
||||
paymentSetting: "Payment Settings",
|
||||
captchaSetting: "Captcha Setting",
|
||||
pipelineSetting: "Pipeline Settings",
|
||||
oauthSetting: "Login Settings",
|
||||
networkSetting: "Network Settings",
|
||||
adminModeSetting: "Admin Mode Settings",
|
||||
adminModeHelper: "enterprise mode : allow to create and manage pipelines, roles, users, etc.\n saas mode : only allow to create and manage pipelines",
|
||||
enterpriseMode: "Enterprise Mode",
|
||||
saasMode: "SaaS Mode",
|
||||
|
||||
showRunStrategy: "Show RunStrategy",
|
||||
showRunStrategyHelper: "Allow modify the run strategy of the task",
|
||||
homePageEnabled: "Enable Home Page",
|
||||
showRunStrategy: "Show RunStrategy",
|
||||
showRunStrategyHelper: "Allow modify the run strategy of the task",
|
||||
homePageEnabled: "Enable Home Page",
|
||||
|
||||
captchaEnabled: "Enable Login Captcha",
|
||||
captchaHelper: "Whether to enable captcha verification for login",
|
||||
captchaType: "Captcha Setting",
|
||||
captchaTest: "Captcha Test",
|
||||
// 保存后再点击测试,请务必测试通过了,再开启登录验证码
|
||||
captchaTestHelper: "Save and click test, please make sure the test is passed before enabling login captcha",
|
||||
captchaEnabled: "Enable Login Captcha",
|
||||
captchaHelper: "Whether to enable captcha verification for login",
|
||||
captchaType: "Captcha Setting",
|
||||
captchaTest: "Captcha Test",
|
||||
// 保存后再点击测试,请务必测试通过了,再开启登录验证码
|
||||
captchaTestHelper: "Save and click test, please make sure the test is passed before enabling login captcha",
|
||||
|
||||
pipelineValidTimeEnabled: "Enable Pipeline Valid Time",
|
||||
pipelineValidTimeEnabledHelper: "Whether to enable the valid time of the pipeline",
|
||||
certDomainAddToMonitorEnabled: "Add Domain to Certificate Monitor",
|
||||
certDomainAddToMonitorEnabledHelper: "Whether to add the domain to the certificate monitor",
|
||||
pipelineValidTimeEnabled: "Enable Pipeline Valid Time",
|
||||
pipelineValidTimeEnabledHelper: "Whether to enable the valid time of the pipeline",
|
||||
certDomainAddToMonitorEnabled: "Add Domain to Certificate Monitor",
|
||||
certDomainAddToMonitorEnabledHelper: "Whether to add the domain to the certificate monitor",
|
||||
|
||||
defaultCertRenewDays: "Default Certificate Renew Days",
|
||||
defaultCertRenewDaysHelper: "Default certificate renewal days, helpful for table list progress bar display",
|
||||
defaultCertRenewDaysRecommend: "Recommend 15",
|
||||
defaultCertRenewDays: "Default Certificate Renew Days",
|
||||
defaultCertRenewDaysHelper: "Default certificate renewal days, helpful for table list progress bar display",
|
||||
defaultCertRenewDaysRecommend: "Recommend 15",
|
||||
|
||||
pipelineMaxRunningCount: "Max Running Count",
|
||||
pipelineMaxRunningCountHelper: "Max running count of the pipeline",
|
||||
pipelineMaxRunningCountRecommend: "Recommend 5-15, default 10",
|
||||
pipelineMaxRunningCount: "Max Running Count",
|
||||
pipelineMaxRunningCountHelper: "Max running count of the pipeline",
|
||||
pipelineMaxRunningCountRecommend: "Recommend 5-15, default 10",
|
||||
|
||||
acmeWalkFromAuthoritative: "Check TXT Record from Authoritative NS",
|
||||
acmeWalkFromAuthoritativeHelper: "Apply certificate when whether to check the TXT record from authoritative NS server first",
|
||||
acmeWalkFromAuthoritative: "Check TXT Record from Authoritative NS",
|
||||
acmeWalkFromAuthoritativeHelper: "Apply certificate when whether to check the TXT record from authoritative NS server first",
|
||||
|
||||
customAcmeManage: "Custom ACME Management",
|
||||
customAcmeManageHelper:
|
||||
"Configure certificate authorities (built-in + custom ACME). Built-in providers cannot be modified or deleted. Custom ACME providers (intranet CA, enterprise CA or any RFC 8555 compatible ACME service) become selectable as certificate authorities in apply tasks and ACME account authorization",
|
||||
customAcmeName: "Name",
|
||||
customAcmeSslProvider: "SSL Provider",
|
||||
customAcmeSslProviderHelper: "Unique identifier, e.g. myca; used to distinguish providers in pipeline and ACME account",
|
||||
customAcmeReverseProxy: "Reverse Proxy",
|
||||
customAcmeReverseProxyHelper:
|
||||
"For example, for Let's Encrypt, configure the reverse proxy on your overseas server: \nproxy_pass https://acme-v02.api.letsencrypt.org/; \nthen fill in your reverse proxy server domain here, without http://",
|
||||
customAcmeAdd: "Add Custom ACME",
|
||||
customAcmeEdit: "Edit Custom ACME",
|
||||
customAcmeNeedEab: "Need EAB",
|
||||
customAcmeBuiltIn: "Built-in",
|
||||
customAcmeTag: "Custom",
|
||||
customAcmeDeleteConfirmTitle: "Delete Custom ACME",
|
||||
customAcmeDeleteConfirmContent: "Deleting '{title}' may affect pipelines using it to apply certificates. Are you sure?",
|
||||
customAcmeSaveCheck: "Name, sslProvider and Directory URL are required",
|
||||
customAcmeSslProviderUnique: "The sslProvider identifier must be unique",
|
||||
customAcmeManage: "Custom ACME Management",
|
||||
customAcmeManageHelper:
|
||||
"Configure certificate authorities (built-in + custom ACME). Built-in providers cannot be modified or deleted. Custom ACME providers (intranet CA, enterprise CA or any RFC 8555 compatible ACME service) become selectable as certificate authorities in apply tasks and ACME account authorization",
|
||||
customAcmeName: "Name",
|
||||
customAcmeSslProvider: "SSL Provider",
|
||||
customAcmeSslProviderHelper: "Unique identifier, e.g. myca; used to distinguish providers in pipeline and ACME account",
|
||||
customAcmeReverseProxy: "Reverse Proxy",
|
||||
customAcmeReverseProxyHelper:
|
||||
"For example, for Let's Encrypt, configure the reverse proxy on your overseas server: \nproxy_pass https://acme-v02.api.letsencrypt.org/; \nthen fill in your reverse proxy server domain here, without http://",
|
||||
customAcmeAdd: "Add Custom ACME",
|
||||
customAcmeEdit: "Edit Custom ACME",
|
||||
customAcmeNeedEab: "Need EAB",
|
||||
customAcmeBuiltIn: "Built-in",
|
||||
customAcmeTag: "Custom",
|
||||
customAcmeDeleteConfirmTitle: "Delete Custom ACME",
|
||||
customAcmeDeleteConfirmContent: "Deleting '{title}' may affect pipelines using it to apply certificates. Are you sure?",
|
||||
customAcmeSaveCheck: "Name, sslProvider and Directory URL are required",
|
||||
customAcmeSslProviderUnique: "The sslProvider identifier must be unique",
|
||||
|
||||
fixedCertExpireDays: "Fixed Cert Expire Days",
|
||||
fixedCertExpireDaysHelper: "Fixed cert expiration days, helpful for table list progress bar display",
|
||||
fixedCertExpireDaysRecommend: "Recommend 90",
|
||||
fixedCertExpireDays: "Fixed Cert Expire Days",
|
||||
fixedCertExpireDaysHelper: "Fixed cert expiration days, helpful for table list progress bar display",
|
||||
fixedCertExpireDaysRecommend: "Recommend 90",
|
||||
|
||||
enableOauth: "Enable OAuth2 Login",
|
||||
oauthEnabledHelper: "Whether to enable OAuth2 login",
|
||||
oauthProviders: "OAuth2 Login Providers",
|
||||
oauthType: "OAuth2 Login Type",
|
||||
oauthConfig: "OAuth2 Login Config",
|
||||
oauthProviderSelectorPlaceholder: "Not Configured",
|
||||
oauthCallback: "Callback URL",
|
||||
oauthCallbackHelper: "Copy this URL to the callback address of the OAuth2 login provider",
|
||||
oauthCallbackCopy: "Copy Callback URL",
|
||||
oauthAutoRegister: "Auto Register User",
|
||||
oauthAutoRegisterCheckedText: "Auto Register",
|
||||
oauthAutoRegisterUnCheckedText: "User Select",
|
||||
oauthAutoRegisterHelper: "Whether to auto register user when login",
|
||||
oauthAutoRedirect: "Auto Redirect to OAuth2 Login",
|
||||
oauthAutoRedirectHelper: "Whether to auto redirect to OAuth2 login when login (using the first enabled OAuth2 login type)",
|
||||
oauthOnly: "OAuth2 Login Only",
|
||||
oauthOnlyHelper: "Only allow OAuth2 login. Password login remains available for 10 minutes after server startup as an emergency window.",
|
||||
enablePasskey: "Enable Passkey Login",
|
||||
passkeyHostnameNotSame: "Passkey hostname must be the same as the main domain",
|
||||
passkeyEnabledHelper:
|
||||
"1、Site must enable https \n2、Domain name must not change, otherwise the registered passkey will be invalid \n3、Domain name must be the same as the main domain, otherwise the registered passkey will be invalid",
|
||||
enableOauth: "Enable OAuth2 Login",
|
||||
oauthEnabledHelper: "Whether to enable OAuth2 login",
|
||||
oauthProviders: "OAuth2 Login Providers",
|
||||
oauthType: "OAuth2 Login Type",
|
||||
oauthConfig: "OAuth2 Login Config",
|
||||
oauthProviderSelectorPlaceholder: "Not Configured",
|
||||
oauthCallback: "Callback URL",
|
||||
oauthCallbackHelper: "Copy this URL to the callback address of the OAuth2 login provider",
|
||||
oauthCallbackCopy: "Copy Callback URL",
|
||||
oauthAutoRegister: "Auto Register User",
|
||||
oauthAutoRegisterCheckedText: "Auto Register",
|
||||
oauthAutoRegisterUnCheckedText: "User Select",
|
||||
oauthAutoRegisterHelper: "Whether to auto register user when login",
|
||||
oauthAutoRedirect: "Auto Redirect to OAuth2 Login",
|
||||
oauthAutoRedirectHelper: "Whether to auto redirect to OAuth2 login when login (using the first enabled OAuth2 login type)",
|
||||
oauthOnly: "OAuth2 Login Only",
|
||||
oauthOnlyHelper: "Only allow OAuth2 login. Password login remains available for 10 minutes after server startup as an emergency window.",
|
||||
enablePasskey: "Enable Passkey Login",
|
||||
passkeyHostnameNotSame: "Passkey hostname must be the same as the main domain",
|
||||
passkeyEnabledHelper:
|
||||
"1、Site must enable https \n2、Domain name must not change, otherwise the registered passkey will be invalid \n3、Domain name must be the same as the main domain, otherwise the registered passkey will be invalid",
|
||||
|
||||
email: {
|
||||
templates: "Email Templates",
|
||||
templateType: "Template Type",
|
||||
templateProvider: "Template Config",
|
||||
email: {
|
||||
templates: "Email Templates",
|
||||
templateType: "Template Type",
|
||||
templateProvider: "Template Config",
|
||||
|
||||
templateSetting: "Email Template Setting",
|
||||
serverSetting: "Email Server Setting",
|
||||
sendTest: "Send Test",
|
||||
templateSetting: "Email Template Setting",
|
||||
serverSetting: "Email Server Setting",
|
||||
sendTest: "Send Test",
|
||||
|
||||
templateProviderSelectorPlaceholder: "Not Configured",
|
||||
},
|
||||
notice: "System Notice",
|
||||
noticeHelper: "System notice, will be displayed on the login page",
|
||||
noticePlaceholder: "System notice",
|
||||
customFooter: "Custom Footer",
|
||||
customFooterHelper: "Custom site footer, displayed at the bottom of the page, support HTML format",
|
||||
customFooterPlaceholder: "Custom footer content",
|
||||
|
||||
environmentVars: "Environment Variables",
|
||||
environmentVarsHelper: "configure the runtime environment variables, one per line, format: KEY=VALUE",
|
||||
commonHeaders: "Common Headers",
|
||||
commonHeadersHelper: "Common headers automatically added to server-side HTTP requests, one per line, format: KEY=VALUE. Existing request headers with the same name are not overwritten.",
|
||||
|
||||
bindUrl: "Bind URL",
|
||||
bindUrlHelper: "Bind URL, used as your site URL in notifications",
|
||||
},
|
||||
templateProviderSelectorPlaceholder: "Not Configured",
|
||||
},
|
||||
notice: "System Notice",
|
||||
noticeHelper: "System notice, will be displayed on the login page",
|
||||
noticePlaceholder: "System notice",
|
||||
customFooter: "Custom Footer",
|
||||
customFooterHelper: "Custom site footer, displayed at the bottom of the page, support HTML format",
|
||||
customFooterPlaceholder: "Custom footer content",
|
||||
|
||||
environmentVars: "Environment Variables",
|
||||
environmentVarsHelper: "configure the runtime environment variables, one per line, format: KEY=VALUE",
|
||||
commonHeaders: "Common Headers",
|
||||
commonHeadersHelper: "Common headers automatically added to server-side HTTP requests, one per line, format: KEY=VALUE. Existing request headers with the same name are not overwritten.",
|
||||
|
||||
bindUrl: "Bind URL",
|
||||
bindUrlHelper: "Bind URL, used as your site URL in notifications",
|
||||
icpRegistrationNumber: "ICP Registration Number",
|
||||
icpPlaceholder: "Guangdong ICP xxxxxxx Number",
|
||||
publicSecurityRegistrationNumber: "Public Security Registration Number",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user