mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-09 05:59:50 +00:00
feat: certificate key algorithm
This commit is contained in:
parent
71f43c5bd4
commit
1ce2a52d70
@ -60,11 +60,12 @@ type Certificate struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ApplyOption struct {
|
type ApplyOption struct {
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
Access string `json:"access"`
|
Access string `json:"access"`
|
||||||
Nameservers string `json:"nameservers"`
|
KeyAlgorithm string `json:"keyAlgorithm"`
|
||||||
Timeout int64 `json:"timeout"`
|
Nameservers string `json:"nameservers"`
|
||||||
|
Timeout int64 `json:"timeout"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ApplyUser struct {
|
type ApplyUser struct {
|
||||||
@ -91,11 +92,10 @@ type Applicant interface {
|
|||||||
|
|
||||||
func Get(record *models.Record) (Applicant, error) {
|
func Get(record *models.Record) (Applicant, error) {
|
||||||
if record.GetString("applyConfig") == "" {
|
if record.GetString("applyConfig") == "" {
|
||||||
return nil, errors.New("apply config is empty")
|
return nil, errors.New("applyConfig is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
applyConfig := &domain.ApplyConfig{}
|
applyConfig := &domain.ApplyConfig{}
|
||||||
|
|
||||||
record.UnmarshalJSONField("applyConfig", applyConfig)
|
record.UnmarshalJSONField("applyConfig", applyConfig)
|
||||||
|
|
||||||
access, err := app.GetApp().Dao().FindRecordById("access", applyConfig.Access)
|
access, err := app.GetApp().Dao().FindRecordById("access", applyConfig.Access)
|
||||||
@ -103,17 +103,23 @@ func Get(record *models.Record) (Applicant, error) {
|
|||||||
return nil, fmt.Errorf("access record not found: %w", err)
|
return nil, fmt.Errorf("access record not found: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
email := applyConfig.Email
|
if applyConfig.Email == "" {
|
||||||
if email == "" {
|
applyConfig.Email = defaultEmail
|
||||||
email = defaultEmail
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if applyConfig.Timeout == 0 {
|
||||||
|
applyConfig.Timeout = defaultTimeout
|
||||||
|
}
|
||||||
|
|
||||||
option := &ApplyOption{
|
option := &ApplyOption{
|
||||||
Email: email,
|
Email: applyConfig.Email,
|
||||||
Domain: record.GetString("domain"),
|
Domain: record.GetString("domain"),
|
||||||
Access: access.GetString("config"),
|
Access: access.GetString("config"),
|
||||||
Nameservers: applyConfig.Nameservers,
|
KeyAlgorithm: applyConfig.KeyAlgorithm,
|
||||||
Timeout: applyConfig.Timeout,
|
Nameservers: applyConfig.Nameservers,
|
||||||
|
Timeout: applyConfig.Timeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch access.GetString("configType") {
|
switch access.GetString("configType") {
|
||||||
case configTypeAliyun:
|
case configTypeAliyun:
|
||||||
return NewAliyun(option), nil
|
return NewAliyun(option), nil
|
||||||
@ -171,7 +177,7 @@ func apply(option *ApplyOption, provider challenge.Provider) (*Certificate, erro
|
|||||||
|
|
||||||
// This CA URL is configured for a local dev instance of Boulder running in Docker in a VM.
|
// This CA URL is configured for a local dev instance of Boulder running in Docker in a VM.
|
||||||
config.CADirURL = sslProviderUrls[sslProvider.Provider]
|
config.CADirURL = sslProviderUrls[sslProvider.Provider]
|
||||||
config.Certificate.KeyType = certcrypto.RSA2048
|
config.Certificate.KeyType = parseKeyAlgorithm(option.KeyAlgorithm)
|
||||||
|
|
||||||
// A client facilitates communication with the CA server.
|
// A client facilitates communication with the CA server.
|
||||||
client, err := lego.NewClient(config)
|
client, err := lego.NewClient(config)
|
||||||
@ -180,7 +186,7 @@ func apply(option *ApplyOption, provider challenge.Provider) (*Certificate, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
challengeOptions := make([]dns01.ChallengeOption, 0)
|
challengeOptions := make([]dns01.ChallengeOption, 0)
|
||||||
nameservers := ParseNameservers(option.Nameservers)
|
nameservers := parseNameservers(option.Nameservers)
|
||||||
if len(nameservers) > 0 {
|
if len(nameservers) > 0 {
|
||||||
challengeOptions = append(challengeOptions, dns01.AddRecursiveNameservers(nameservers))
|
challengeOptions = append(challengeOptions, dns01.AddRecursiveNameservers(nameservers))
|
||||||
}
|
}
|
||||||
@ -195,7 +201,6 @@ func apply(option *ApplyOption, provider challenge.Provider) (*Certificate, erro
|
|||||||
myUser.Registration = reg
|
myUser.Registration = reg
|
||||||
|
|
||||||
domains := strings.Split(option.Domain, ";")
|
domains := strings.Split(option.Domain, ";")
|
||||||
|
|
||||||
request := certificate.ObtainRequest{
|
request := certificate.ObtainRequest{
|
||||||
Domains: domains,
|
Domains: domains,
|
||||||
Bundle: true,
|
Bundle: true,
|
||||||
@ -231,7 +236,6 @@ func getReg(client *lego.Client, sslProvider *SSLProviderConfig) (*registration.
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
err = errors.New("unknown ssl provider")
|
err = errors.New("unknown ssl provider")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -241,15 +245,13 @@ func getReg(client *lego.Client, sslProvider *SSLProviderConfig) (*registration.
|
|||||||
return reg, nil
|
return reg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseNameservers(ns string) []string {
|
func parseNameservers(ns string) []string {
|
||||||
nameservers := make([]string, 0)
|
nameservers := make([]string, 0)
|
||||||
|
|
||||||
lines := strings.Split(ns, ";")
|
lines := strings.Split(ns, ";")
|
||||||
|
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
|
|
||||||
line = strings.TrimSpace(line)
|
line = strings.TrimSpace(line)
|
||||||
|
|
||||||
if line == "" {
|
if line == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -259,3 +261,22 @@ func ParseNameservers(ns string) []string {
|
|||||||
|
|
||||||
return nameservers
|
return nameservers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseKeyAlgorithm(algo string) certcrypto.KeyType {
|
||||||
|
switch algo {
|
||||||
|
case "RSA2048":
|
||||||
|
return certcrypto.RSA2048
|
||||||
|
case "RSA3072":
|
||||||
|
return certcrypto.RSA3072
|
||||||
|
case "RSA4096":
|
||||||
|
return certcrypto.RSA4096
|
||||||
|
case "RSA8192":
|
||||||
|
return certcrypto.RSA8192
|
||||||
|
case "EC256":
|
||||||
|
return certcrypto.EC256
|
||||||
|
case "EC384":
|
||||||
|
return certcrypto.EC384
|
||||||
|
default:
|
||||||
|
return certcrypto.RSA2048
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package domain
|
package domain
|
||||||
|
|
||||||
type ApplyConfig struct {
|
type ApplyConfig struct {
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Access string `json:"access"`
|
Access string `json:"access"`
|
||||||
Timeout int64 `json:"timeout"`
|
KeyAlgorithm string `json:"keyAlgorithm"`
|
||||||
Nameservers string `json:"nameservers"`
|
Nameservers string `json:"nameservers"`
|
||||||
|
Timeout int64 `json:"timeout"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeployConfig struct {
|
type DeployConfig struct {
|
||||||
|
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" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Certimate - Your Trusted SSL Automation Partner</title>
|
<title>Certimate - Your Trusted SSL Automation Partner</title>
|
||||||
<script type="module" crossorigin src="/assets/index-DIhd7QG6.js"></script>
|
<script type="module" crossorigin src="/assets/index-C20g8xcX.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-CV_7sKTK.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-YqBWA4KK.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-background">
|
<body class="bg-background">
|
||||||
<div id="root"></div>
|
<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",
|
"@hookform/resolvers": "^3.9.0",
|
||||||
"@radix-ui/react-accordion": "^1.2.0",
|
"@radix-ui/react-accordion": "^1.2.0",
|
||||||
"@radix-ui/react-alert-dialog": "^1.1.1",
|
"@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-dialog": "^1.1.1",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||||
"@radix-ui/react-label": "^2.1.0",
|
"@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": {
|
"node_modules/@radix-ui/react-alert-dialog": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.1.tgz",
|
"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": {
|
"node_modules/@radix-ui/react-collapsible": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-collapsible/-/react-collapsible-1.1.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@radix-ui/react-collapsible/-/react-collapsible-1.1.1.tgz",
|
||||||
"integrity": "sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==",
|
"integrity": "sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-ui/primitive": "1.1.0",
|
"@radix-ui/primitive": "1.1.0",
|
||||||
"@radix-ui/react-compose-refs": "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-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-primitive": "2.0.0",
|
||||||
"@radix-ui/react-use-controllable-state": "1.1.0",
|
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||||
"@radix-ui/react-use-layout-effect": "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": {
|
"node_modules/@radix-ui/react-collection": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
"@hookform/resolvers": "^3.9.0",
|
"@hookform/resolvers": "^3.9.0",
|
||||||
"@radix-ui/react-accordion": "^1.2.0",
|
"@radix-ui/react-accordion": "^1.2.0",
|
||||||
"@radix-ui/react-alert-dialog": "^1.1.1",
|
"@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-dialog": "^1.1.1",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||||
"@radix-ui/react-label": "^2.1.0",
|
"@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 = {
|
export type ApplyConfig = {
|
||||||
access: string;
|
access: string;
|
||||||
email: string;
|
email: string;
|
||||||
timeout?: number;
|
keyAlgorithm?: string;
|
||||||
nameservers?: string;
|
nameservers?: string;
|
||||||
|
timeout?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Statistic = {
|
export type Statistic = {
|
||||||
|
@ -30,15 +30,17 @@
|
|||||||
"domain.application.form.domain.changed.message": "Domain updated successfully",
|
"domain.application.form.domain.changed.message": "Domain updated successfully",
|
||||||
"domain.application.form.email.label": "Email",
|
"domain.application.form.email.label": "Email",
|
||||||
"domain.application.form.email.tips": "(A email is required to apply for a certificate)",
|
"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.add": "Add Email",
|
||||||
"domain.application.form.email.list": "Email List",
|
"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.label": "DNS Provider Authorization Configuration",
|
||||||
"domain.application.form.access.placeholder": "Please select 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.access.list": "Provider Authorization Configurations",
|
||||||
"domain.application.form.timeout.label": "Timeout",
|
"domain.application.form.advanced_settings.label": "Advanced Settings",
|
||||||
"domain.application.form.timeoue.placeholder": "Timeout (seconds)",
|
"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.application.unsaved.message": "Please save applyment configuration first",
|
||||||
|
|
||||||
"domain.deployment.tab": "Deploy Settings",
|
"domain.deployment.tab": "Deploy Settings",
|
||||||
|
@ -30,15 +30,17 @@
|
|||||||
"domain.application.form.domain.changed.message": "域名编辑成功",
|
"domain.application.form.domain.changed.message": "域名编辑成功",
|
||||||
"domain.application.form.email.label": "邮箱",
|
"domain.application.form.email.label": "邮箱",
|
||||||
"domain.application.form.email.tips": "(申请证书需要提供邮箱)",
|
"domain.application.form.email.tips": "(申请证书需要提供邮箱)",
|
||||||
|
"domain.application.form.email.placeholder": "请选择邮箱",
|
||||||
"domain.application.form.email.add": "添加邮箱",
|
"domain.application.form.email.add": "添加邮箱",
|
||||||
"domain.application.form.email.list": "邮箱列表",
|
"domain.application.form.email.list": "邮箱列表",
|
||||||
"domain.application.form.email.errmsg.empty": "请选择邮箱",
|
|
||||||
"domain.application.form.access.label": "DNS 服务商授权配置",
|
"domain.application.form.access.label": "DNS 服务商授权配置",
|
||||||
"domain.application.form.access.placeholder": "请选择 DNS 服务商授权配置",
|
"domain.application.form.access.placeholder": "请选择 DNS 服务商授权配置",
|
||||||
"domain.application.form.access.errmsg.empty": "请选择 DNS 服务商授权配置",
|
|
||||||
"domain.application.form.access.list": "已有的 DNS 服务商授权配置",
|
"domain.application.form.access.list": "已有的 DNS 服务商授权配置",
|
||||||
"domain.application.form.timeout.label": "超时时间",
|
"domain.application.form.advanced_settings.label": "高级设置",
|
||||||
"domain.application.form.timeoue.placeholder": "超时时间(单位:秒)",
|
"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.application.unsaved.message": "请先保存申请配置",
|
||||||
|
|
||||||
"domain.deployment.tab": "部署配置",
|
"domain.deployment.tab": "部署配置",
|
||||||
|
@ -4,11 +4,12 @@ import { useForm } from "react-hook-form";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { Plus } from "lucide-react";
|
import { ChevronsUpDown, Plus } from "lucide-react";
|
||||||
import { ClientResponseError } from "pocketbase";
|
import { ClientResponseError } from "pocketbase";
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb";
|
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 { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/ui/select";
|
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(),
|
email: z.string().email("common.errmsg.email_invalid").optional(),
|
||||||
access: z.string().regex(/^[a-zA-Z0-9]+$/, {
|
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(),
|
nameservers: z.string().optional(),
|
||||||
timeout: z.number().optional(),
|
timeout: z.number().optional(),
|
||||||
});
|
});
|
||||||
@ -71,6 +73,7 @@ const Edit = () => {
|
|||||||
domain: "",
|
domain: "",
|
||||||
email: "",
|
email: "",
|
||||||
access: "",
|
access: "",
|
||||||
|
keyAlgorithm: "RSA2048",
|
||||||
nameservers: "",
|
nameservers: "",
|
||||||
timeout: 60,
|
timeout: 60,
|
||||||
},
|
},
|
||||||
@ -83,6 +86,7 @@ const Edit = () => {
|
|||||||
domain: domain.domain,
|
domain: domain.domain,
|
||||||
email: domain.applyConfig?.email,
|
email: domain.applyConfig?.email,
|
||||||
access: domain.applyConfig?.access,
|
access: domain.applyConfig?.access,
|
||||||
|
keyAlgorithm: domain.applyConfig?.keyAlgorithm,
|
||||||
nameservers: domain.applyConfig?.nameservers,
|
nameservers: domain.applyConfig?.nameservers,
|
||||||
timeout: domain.applyConfig?.timeout,
|
timeout: domain.applyConfig?.timeout,
|
||||||
});
|
});
|
||||||
@ -101,6 +105,7 @@ const Edit = () => {
|
|||||||
applyConfig: {
|
applyConfig: {
|
||||||
email: data.email ?? "",
|
email: data.email ?? "",
|
||||||
access: data.access,
|
access: data.access,
|
||||||
|
keyAlgorithm: data.keyAlgorithm,
|
||||||
nameservers: data.nameservers,
|
nameservers: data.nameservers,
|
||||||
timeout: data.timeout,
|
timeout: data.timeout,
|
||||||
},
|
},
|
||||||
@ -235,6 +240,7 @@ const Edit = () => {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 邮箱 */}
|
{/* 邮箱 */}
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
@ -261,7 +267,7 @@ const Edit = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder={t("domain.application.form.email.errmsg.empty")} />
|
<SelectValue placeholder={t("domain.application.form.email.placeholder")} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
@ -280,7 +286,8 @@ const Edit = () => {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{/* 授权 */}
|
|
||||||
|
{/* DNS 服务商授权 */}
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="access"
|
name="access"
|
||||||
@ -332,48 +339,95 @@ const Edit = () => {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 超时时间 */}
|
<div>
|
||||||
<FormField
|
<hr />
|
||||||
control={form.control}
|
<Collapsible>
|
||||||
name="timeout"
|
<CollapsibleTrigger className="w-full my-4">
|
||||||
render={({ field }) => (
|
<div className="flex items-center justify-between space-x-4">
|
||||||
<FormItem>
|
<span className="flex-1 text-sm text-gray-600 text-left">{t("domain.application.form.advanced_settings.label")}</span>
|
||||||
<FormLabel>{t("domain.application.form.timeout.label")}</FormLabel>
|
<ChevronsUpDown className="h-4 w-4" />
|
||||||
<FormControl>
|
</div>
|
||||||
<Input
|
</CollapsibleTrigger>
|
||||||
type="number"
|
<CollapsibleContent>
|
||||||
placeholder={t("ddomain.application.form.timeout.placeholder")}
|
<div className="flex flex-col space-y-8">
|
||||||
{...field}
|
{/* 证书算法 */}
|
||||||
value={field.value}
|
<FormField
|
||||||
onChange={(e) => {
|
control={form.control}
|
||||||
form.setValue("timeout", parseInt(e.target.value));
|
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 />
|
{/* DNS */}
|
||||||
</FormItem>
|
<FormField
|
||||||
)}
|
control={form.control}
|
||||||
/>
|
name="nameservers"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<StringList
|
||||||
|
value={field.value ?? ""}
|
||||||
|
onValueChange={(val: string) => {
|
||||||
|
form.setValue("nameservers", val);
|
||||||
|
}}
|
||||||
|
valueType="dns"
|
||||||
|
></StringList>
|
||||||
|
|
||||||
{/* nameservers */}
|
<FormMessage />
|
||||||
<FormField
|
</FormItem>
|
||||||
control={form.control}
|
)}
|
||||||
name="nameservers"
|
/>
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<StringList
|
|
||||||
value={field.value ?? ""}
|
|
||||||
onValueChange={(val: string) => {
|
|
||||||
form.setValue("nameservers", val);
|
|
||||||
}}
|
|
||||||
valueType="dns"
|
|
||||||
></StringList>
|
|
||||||
|
|
||||||
<FormMessage />
|
{/* DNS 超时时间 */}
|
||||||
</FormItem>
|
<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">
|
<div className="flex justify-end">
|
||||||
<Button type="submit">{domain?.id ? t("common.save") : t("common.next")}</Button>
|
<Button type="submit">{domain?.id ? t("common.save") : t("common.next")}</Button>
|
||||||
|
@ -70,10 +70,20 @@ module.exports = {
|
|||||||
height: "0",
|
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: {
|
animation: {
|
||||||
"accordion-down": "accordion-down 0.2s ease-out",
|
"accordion-down": "accordion-down 0.2s ease-out",
|
||||||
"accordion-up": "accordion-up 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",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user