diff --git a/internal/domain/access.go b/internal/domain/access.go
index 889d37fa..bd4f41c1 100644
--- a/internal/domain/access.go
+++ b/internal/domain/access.go
@@ -32,6 +32,11 @@ type QiniuAccess struct {
SecretKey string `json:"secretKey"`
}
+type DogeCloudAccess struct {
+ AccessKey string `json:"accessKey"`
+ SecretKey string `json:"secretKey"`
+}
+
type NameSiloAccess struct {
ApiKey string `json:"apiKey"`
}
diff --git a/ui/public/imgs/providers/dogecloud.svg b/ui/public/imgs/providers/dogecloud.svg
new file mode 100644
index 00000000..253f9ae7
--- /dev/null
+++ b/ui/public/imgs/providers/dogecloud.svg
@@ -0,0 +1 @@
+
diff --git a/ui/public/imgs/providers/google.svg b/ui/public/imgs/providers/google.svg
index d5f4dbeb..120a7921 100644
--- a/ui/public/imgs/providers/google.svg
+++ b/ui/public/imgs/providers/google.svg
@@ -1,28 +1 @@
-
-
-
\ No newline at end of file
+
diff --git a/ui/src/components/certimate/AccessDogeCloudForm.tsx b/ui/src/components/certimate/AccessDogeCloudForm.tsx
new file mode 100644
index 00000000..66c8db6f
--- /dev/null
+++ b/ui/src/components/certimate/AccessDogeCloudForm.tsx
@@ -0,0 +1,188 @@
+import { useForm } from "react-hook-form";
+import { useTranslation } from "react-i18next";
+import z from "zod";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { ClientResponseError } from "pocketbase";
+
+import { Button } from "@/components/ui/button";
+import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
+import { Input } from "@/components/ui/input";
+import { PbErrorData } from "@/domain/base";
+import { accessProvidersMap, accessTypeFormSchema, type Access, type DogeCloudConfig } from "@/domain/access";
+import { save } from "@/repository/access";
+import { useConfigContext } from "@/providers/config";
+
+type AccessDogeCloudFormProps = {
+ op: "add" | "edit" | "copy";
+ data?: Access;
+ onAfterReq: () => void;
+};
+
+const AccessDogeCloudForm = ({ data, op, onAfterReq }: AccessDogeCloudFormProps) => {
+ const { addAccess, updateAccess } = useConfigContext();
+ const { t } = useTranslation();
+ const formSchema = z.object({
+ id: z.string().optional(),
+ name: z
+ .string()
+ .min(1, "access.authorization.form.name.placeholder")
+ .max(64, t("common.errmsg.string_max", { max: 64 })),
+ configType: accessTypeFormSchema,
+ accessKey: z.string().min(1, "access.authorization.form.access_key.placeholder").max(64),
+ secretKey: z.string().min(1, "access.authorization.form.secret_key.placeholder").max(64),
+ });
+
+ let config: DogeCloudConfig = {
+ accessKey: "",
+ secretKey: "",
+ };
+ if (data) config = data.config as DogeCloudConfig;
+
+ const form = useForm>({
+ resolver: zodResolver(formSchema),
+ defaultValues: {
+ id: data?.id,
+ name: data?.name || "",
+ configType: "dogecloud",
+ accessKey: config.accessKey,
+ secretKey: config.secretKey,
+ },
+ });
+
+ const onSubmit = async (data: z.infer) => {
+ const req: Access = {
+ id: data.id as string,
+ name: data.name,
+ configType: data.configType,
+ usage: accessProvidersMap.get(data.configType)!.usage,
+ config: {
+ accessKey: data.accessKey,
+ secretKey: data.secretKey,
+ },
+ };
+
+ try {
+ req.id = op == "copy" ? "" : req.id;
+ const rs = await save(req);
+
+ onAfterReq();
+
+ req.id = rs.id;
+ req.created = rs.created;
+ req.updated = rs.updated;
+ if (data.id && op == "edit") {
+ updateAccess(req);
+ return;
+ }
+ addAccess(req);
+ } catch (e) {
+ const err = e as ClientResponseError;
+
+ Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
+ form.setError(key as keyof z.infer, {
+ type: "manual",
+ message: value.message,
+ });
+ });
+
+ return;
+ }
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default AccessDogeCloudForm;
diff --git a/ui/src/components/certimate/AccessEditDialog.tsx b/ui/src/components/certimate/AccessEditDialog.tsx
index afb23068..f5c3c65e 100644
--- a/ui/src/components/certimate/AccessEditDialog.tsx
+++ b/ui/src/components/certimate/AccessEditDialog.tsx
@@ -9,6 +9,7 @@ import AccessAliyunForm from "./AccessAliyunForm";
import AccessTencentForm from "./AccessTencentForm";
import AccessHuaweiCloudForm from "./AccessHuaweicloudForm";
import AccessQiniuForm from "./AccessQiniuForm";
+import AccessDogeCloudForm from "./AccessDogeCloudForm";
import AccessAwsForm from "./AccessAwsForm";
import AccessCloudflareForm from "./AccessCloudflareForm";
import AccessNamesiloForm from "./AccessNamesiloForm";
@@ -82,6 +83,17 @@ const AccessEditDialog = ({ trigger, op, data, className }: AccessEditProps) =>
/>
);
break;
+ case "dogecloud":
+ childComponent = (
+ {
+ setOpen(false);
+ }}
+ />
+ );
+ break;
case "aws":
childComponent = (
= n
["aliyun", "common.provider.aliyun", "/imgs/providers/aliyun.svg", "all", "阿里云:alibaba cloud"],
["tencent", "common.provider.tencent", "/imgs/providers/tencent.svg", "all", "腾讯云:tencent cloud"],
["huaweicloud", "common.provider.huaweicloud", "/imgs/providers/huaweicloud.svg", "all", "华为云:huawei cloud"],
- ["qiniu", "common.provider.qiniu", "/imgs/providers/qiniu.svg", "deploy", "七牛:qiniu"],
+ ["qiniu", "common.provider.qiniu", "/imgs/providers/qiniu.svg", "deploy", "七牛云:qiniu"],
+ ["dogecloud", "common.provider.dogecloud", "/imgs/providers/dogecloud.svg", "deploy", "多吉云:dogecloud:doge cloud"],
["aws", "common.provider.aws", "/imgs/providers/aws.svg", "apply", "亚马逊:amazon:aws"],
["cloudflare", "common.provider.cloudflare", "/imgs/providers/cloudflare.svg", "apply", "cloudflare:cf:cloud flare"],
["namesilo", "common.provider.namesilo", "/imgs/providers/namesilo.svg", "apply", "namesilo"],
@@ -35,6 +36,7 @@ export const accessTypeFormSchema = z.union(
z.literal("tencent"),
z.literal("huaweicloud"),
z.literal("qiniu"),
+ z.literal("dogecloud"),
z.literal("aws"),
z.literal("cloudflare"),
z.literal("namesilo"),
@@ -60,6 +62,7 @@ export type Access = {
| TencentConfig
| HuaweiCloudConfig
| QiniuConfig
+ | DogeCloudConfig
| AwsConfig
| CloudflareConfig
| NamesiloConfig
@@ -96,6 +99,11 @@ export type QiniuConfig = {
secretKey: string;
};
+export type DogeCloudConfig = {
+ accessKey: string;
+ secretKey: string;
+};
+
export type AwsConfig = {
region: string;
accessKeyId: string;
diff --git a/ui/src/i18n/locales/en/nls.common.json b/ui/src/i18n/locales/en/nls.common.json
index fc545b4c..66c63104 100644
--- a/ui/src/i18n/locales/en/nls.common.json
+++ b/ui/src/i18n/locales/en/nls.common.json
@@ -70,6 +70,7 @@
"common.provider.huaweicloud.elb": "Huawei Cloud - ELB",
"common.provider.qiniu": "Qiniu Cloud",
"common.provider.qiniu.cdn": "Qiniu Cloud - CDN",
+ "common.provider.dogecloud": "Doge Cloud",
"common.provider.aws": "AWS",
"common.provider.cloudflare": "Cloudflare",
"common.provider.namesilo": "Namesilo",
diff --git a/ui/src/i18n/locales/zh/nls.common.json b/ui/src/i18n/locales/zh/nls.common.json
index 487f90c5..aec122d2 100644
--- a/ui/src/i18n/locales/zh/nls.common.json
+++ b/ui/src/i18n/locales/zh/nls.common.json
@@ -70,6 +70,7 @@
"common.provider.huaweicloud.elb": "华为云 - 弹性负载均衡 ELB",
"common.provider.qiniu": "七牛云",
"common.provider.qiniu.cdn": "七牛云 - 内容分发网络 CDN",
+ "common.provider.dogecloud": "多吉云",
"common.provider.aws": "AWS",
"common.provider.cloudflare": "Cloudflare",
"common.provider.namesilo": "Namesilo",