mirror of
https://github.com/usual2970/certimate.git
synced 2025-10-05 05:54:53 +00:00
feat: certificate key algorithm
This commit is contained in:
329
ui/dist/assets/index-C20g8xcX.js
vendored
Normal file
329
ui/dist/assets/index-C20g8xcX.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
ui/dist/assets/index-CV_7sKTK.css
vendored
1
ui/dist/assets/index-CV_7sKTK.css
vendored
File diff suppressed because one or more lines are too long
324
ui/dist/assets/index-DIhd7QG6.js
vendored
324
ui/dist/assets/index-DIhd7QG6.js
vendored
File diff suppressed because one or more lines are too long
1
ui/dist/assets/index-YqBWA4KK.css
vendored
Normal file
1
ui/dist/assets/index-YqBWA4KK.css
vendored
Normal file
File diff suppressed because one or more lines are too long
4
ui/dist/index.html
vendored
4
ui/dist/index.html
vendored
@@ -5,8 +5,8 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Certimate - Your Trusted SSL Automation Partner</title>
|
||||
<script type="module" crossorigin src="/assets/index-DIhd7QG6.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CV_7sKTK.css">
|
||||
<script type="module" crossorigin src="/assets/index-C20g8xcX.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-YqBWA4KK.css">
|
||||
</head>
|
||||
<body class="bg-background">
|
||||
<div id="root"></div>
|
||||
|
77
ui/package-lock.json
generated
77
ui/package-lock.json
generated
@@ -11,6 +11,7 @@
|
||||
"@hookform/resolvers": "^3.9.0",
|
||||
"@radix-ui/react-accordion": "^1.2.0",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.1",
|
||||
"@radix-ui/react-collapsible": "^1.1.1",
|
||||
"@radix-ui/react-dialog": "^1.1.1",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||
"@radix-ui/react-label": "^2.1.0",
|
||||
@@ -1184,6 +1185,35 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-collapsible": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-collapsible/-/react-collapsible-1.1.0.tgz",
|
||||
"integrity": "sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.0",
|
||||
"@radix-ui/react-compose-refs": "1.1.0",
|
||||
"@radix-ui/react-context": "1.1.0",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-presence": "1.1.0",
|
||||
"@radix-ui/react-primitive": "2.0.0",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-alert-dialog": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.1.tgz",
|
||||
@@ -1234,15 +1264,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collapsible": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-collapsible/-/react-collapsible-1.1.0.tgz",
|
||||
"integrity": "sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==",
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-collapsible/-/react-collapsible-1.1.1.tgz",
|
||||
"integrity": "sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.0",
|
||||
"@radix-ui/react-compose-refs": "1.1.0",
|
||||
"@radix-ui/react-context": "1.1.0",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-presence": "1.1.0",
|
||||
"@radix-ui/react-presence": "1.1.1",
|
||||
"@radix-ui/react-primitive": "2.0.0",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
@@ -1262,6 +1292,43 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-context": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-context/-/react-context-1.1.1.tgz",
|
||||
"integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-presence": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-presence/-/react-presence-1.1.1.tgz",
|
||||
"integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.0",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collection": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
|
||||
|
@@ -13,6 +13,7 @@
|
||||
"@hookform/resolvers": "^3.9.0",
|
||||
"@radix-ui/react-accordion": "^1.2.0",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.1",
|
||||
"@radix-ui/react-collapsible": "^1.1.1",
|
||||
"@radix-ui/react-dialog": "^1.1.1",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||
"@radix-ui/react-label": "^2.1.0",
|
||||
|
22
ui/src/components/ui/collapsible.tsx
Normal file
22
ui/src/components/ui/collapsible.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import * as React from "react";
|
||||
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Collapsible = CollapsiblePrimitive.Root;
|
||||
|
||||
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
|
||||
|
||||
const CollapsibleContent = React.forwardRef<
|
||||
React.ElementRef<typeof CollapsiblePrimitive.CollapsibleContent>,
|
||||
React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.CollapsibleContent>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<CollapsiblePrimitive.CollapsibleContent
|
||||
ref={ref}
|
||||
className={cn("overflow-y-hidden transition-all data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CollapsibleContent.displayName = CollapsiblePrimitive.CollapsibleContent.displayName;
|
||||
|
||||
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|
@@ -50,8 +50,9 @@ export type DeployConfig = {
|
||||
export type ApplyConfig = {
|
||||
access: string;
|
||||
email: string;
|
||||
timeout?: number;
|
||||
keyAlgorithm?: string;
|
||||
nameservers?: string;
|
||||
timeout?: number;
|
||||
};
|
||||
|
||||
export type Statistic = {
|
||||
|
@@ -30,15 +30,17 @@
|
||||
"domain.application.form.domain.changed.message": "Domain updated successfully",
|
||||
"domain.application.form.email.label": "Email",
|
||||
"domain.application.form.email.tips": "(A email is required to apply for a certificate)",
|
||||
"domain.application.form.email.placeholder": "Please select email",
|
||||
"domain.application.form.email.add": "Add Email",
|
||||
"domain.application.form.email.list": "Email List",
|
||||
"domain.application.form.email.errmsg.empty": "Please select email",
|
||||
"domain.application.form.access.label": "DNS Provider Authorization Configuration",
|
||||
"domain.application.form.access.placeholder": "Please select DNS provider authorization configuration",
|
||||
"domain.application.form.access.errmsg.empty": "Please select DNS provider authorization configuration",
|
||||
"domain.application.form.access.list": "Provider Authorization Configurations",
|
||||
"domain.application.form.timeout.label": "Timeout",
|
||||
"domain.application.form.timeoue.placeholder": "Timeout (seconds)",
|
||||
"domain.application.form.advanced_settings.label": "Advanced Settings",
|
||||
"domain.application.form.key_algorithm.label": "Certificate Key Algorithm",
|
||||
"domain.application.form.key_algorithm.placeholder": "Please select certificate key algorithm",
|
||||
"domain.application.form.timeout.label": "DNS Propagation Timeout (seconds)",
|
||||
"domain.application.form.timeoue.placeholder": "Please enter maximum waiting time for DNS propagation",
|
||||
"domain.application.unsaved.message": "Please save applyment configuration first",
|
||||
|
||||
"domain.deployment.tab": "Deploy Settings",
|
||||
|
@@ -30,15 +30,17 @@
|
||||
"domain.application.form.domain.changed.message": "域名编辑成功",
|
||||
"domain.application.form.email.label": "邮箱",
|
||||
"domain.application.form.email.tips": "(申请证书需要提供邮箱)",
|
||||
"domain.application.form.email.placeholder": "请选择邮箱",
|
||||
"domain.application.form.email.add": "添加邮箱",
|
||||
"domain.application.form.email.list": "邮箱列表",
|
||||
"domain.application.form.email.errmsg.empty": "请选择邮箱",
|
||||
"domain.application.form.access.label": "DNS 服务商授权配置",
|
||||
"domain.application.form.access.placeholder": "请选择 DNS 服务商授权配置",
|
||||
"domain.application.form.access.errmsg.empty": "请选择 DNS 服务商授权配置",
|
||||
"domain.application.form.access.list": "已有的 DNS 服务商授权配置",
|
||||
"domain.application.form.timeout.label": "超时时间",
|
||||
"domain.application.form.timeoue.placeholder": "超时时间(单位:秒)",
|
||||
"domain.application.form.advanced_settings.label": "高级设置",
|
||||
"domain.application.form.key_algorithm.label": "数字证书算法",
|
||||
"domain.application.form.key_algorithm.placeholder": "请选择数字证书算法",
|
||||
"domain.application.form.timeout.label": "DNS 传播检查超时时间(单位:秒)",
|
||||
"domain.application.form.timeoue.placeholder": "请输入 DNS 传播检查超时时间",
|
||||
"domain.application.unsaved.message": "请先保存申请配置",
|
||||
|
||||
"domain.deployment.tab": "部署配置",
|
||||
|
@@ -4,11 +4,12 @@ import { useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import z from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Plus } from "lucide-react";
|
||||
import { ChevronsUpDown, Plus } from "lucide-react";
|
||||
import { ClientResponseError } from "pocketbase";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb";
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
@@ -58,8 +59,9 @@ const Edit = () => {
|
||||
}),
|
||||
email: z.string().email("common.errmsg.email_invalid").optional(),
|
||||
access: z.string().regex(/^[a-zA-Z0-9]+$/, {
|
||||
message: "domain.application.form.access.errmsg.empty",
|
||||
message: "domain.application.form.access.placeholder",
|
||||
}),
|
||||
keyAlgorithm: z.string().optional(),
|
||||
nameservers: z.string().optional(),
|
||||
timeout: z.number().optional(),
|
||||
});
|
||||
@@ -71,6 +73,7 @@ const Edit = () => {
|
||||
domain: "",
|
||||
email: "",
|
||||
access: "",
|
||||
keyAlgorithm: "RSA2048",
|
||||
nameservers: "",
|
||||
timeout: 60,
|
||||
},
|
||||
@@ -83,6 +86,7 @@ const Edit = () => {
|
||||
domain: domain.domain,
|
||||
email: domain.applyConfig?.email,
|
||||
access: domain.applyConfig?.access,
|
||||
keyAlgorithm: domain.applyConfig?.keyAlgorithm,
|
||||
nameservers: domain.applyConfig?.nameservers,
|
||||
timeout: domain.applyConfig?.timeout,
|
||||
});
|
||||
@@ -101,6 +105,7 @@ const Edit = () => {
|
||||
applyConfig: {
|
||||
email: data.email ?? "",
|
||||
access: data.access,
|
||||
keyAlgorithm: data.keyAlgorithm,
|
||||
nameservers: data.nameservers,
|
||||
timeout: data.timeout,
|
||||
},
|
||||
@@ -235,6 +240,7 @@ const Edit = () => {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* 邮箱 */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
@@ -261,7 +267,7 @@ const Edit = () => {
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t("domain.application.form.email.errmsg.empty")} />
|
||||
<SelectValue placeholder={t("domain.application.form.email.placeholder")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
@@ -280,7 +286,8 @@ const Edit = () => {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{/* 授权 */}
|
||||
|
||||
{/* DNS 服务商授权 */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="access"
|
||||
@@ -332,48 +339,95 @@ const Edit = () => {
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* 超时时间 */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="timeout"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("domain.application.form.timeout.label")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder={t("ddomain.application.form.timeout.placeholder")}
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={(e) => {
|
||||
form.setValue("timeout", parseInt(e.target.value));
|
||||
}}
|
||||
<div>
|
||||
<hr />
|
||||
<Collapsible>
|
||||
<CollapsibleTrigger className="w-full my-4">
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<span className="flex-1 text-sm text-gray-600 text-left">{t("domain.application.form.advanced_settings.label")}</span>
|
||||
<ChevronsUpDown className="h-4 w-4" />
|
||||
</div>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
<div className="flex flex-col space-y-8">
|
||||
{/* 证书算法 */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="keyAlgorithm"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("domain.application.form.key_algorithm.label")}</FormLabel>
|
||||
<Select
|
||||
{...field}
|
||||
value={field.value}
|
||||
onValueChange={(value) => {
|
||||
form.setValue("keyAlgorithm", value);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t("domain.application.form.key_algorithm.placeholder")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="RSA2048">RSA2048</SelectItem>
|
||||
<SelectItem value="RSA3072">RSA3072</SelectItem>
|
||||
<SelectItem value="RSA4096">RSA4096</SelectItem>
|
||||
<SelectItem value="RSA8192">RSA8192</SelectItem>
|
||||
<SelectItem value="EC256">EC256</SelectItem>
|
||||
<SelectItem value="EC384">EC384</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{/* DNS */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="nameservers"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<StringList
|
||||
value={field.value ?? ""}
|
||||
onValueChange={(val: string) => {
|
||||
form.setValue("nameservers", val);
|
||||
}}
|
||||
valueType="dns"
|
||||
></StringList>
|
||||
|
||||
{/* nameservers */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="nameservers"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<StringList
|
||||
value={field.value ?? ""}
|
||||
onValueChange={(val: string) => {
|
||||
form.setValue("nameservers", val);
|
||||
}}
|
||||
valueType="dns"
|
||||
></StringList>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{/* DNS 超时时间 */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="timeout"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("domain.application.form.timeout.label")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder={t("domain.application.form.timeout.placeholder")}
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={(e) => {
|
||||
form.setValue("timeout", parseInt(e.target.value));
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<Button type="submit">{domain?.id ? t("common.save") : t("common.next")}</Button>
|
||||
|
@@ -70,10 +70,20 @@ module.exports = {
|
||||
height: "0",
|
||||
},
|
||||
},
|
||||
"collapsible-down": {
|
||||
from: { height: 0 },
|
||||
to: { height: "var(--radix-collapsible-content-height)" },
|
||||
},
|
||||
"collapsible-up": {
|
||||
from: { height: "var(--radix-collapsible-content-height)" },
|
||||
to: { height: 0 },
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
"accordion-down": "accordion-down 0.2s ease-out",
|
||||
"accordion-up": "accordion-up 0.2s ease-out",
|
||||
"collapsible-down": "collapsible-down 0.2s ease-out",
|
||||
"collapsible-up": "collapsible-up 0.2s ease-out",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
Reference in New Issue
Block a user