feat: support jks format
This commit is contained in:
@@ -26,6 +26,9 @@ const DeployToLocal = () => {
|
||||
certPath: "/etc/nginx/ssl/nginx.crt",
|
||||
keyPath: "/etc/nginx/ssl/nginx.key",
|
||||
pfxPassword: "",
|
||||
jksAlias: "",
|
||||
jksKeypass: "",
|
||||
jksStorepass: "",
|
||||
shell: "sh",
|
||||
preCommand: "",
|
||||
command: "sudo service nginx reload",
|
||||
@@ -40,7 +43,7 @@ const DeployToLocal = () => {
|
||||
|
||||
const formSchema = z
|
||||
.object({
|
||||
format: z.union([z.literal("pem"), z.literal("pfx")], {
|
||||
format: z.union([z.literal("pem"), z.literal("pfx"), z.literal("jks")], {
|
||||
message: t("domain.deployment.form.file_format.placeholder"),
|
||||
}),
|
||||
certPath: z
|
||||
@@ -52,6 +55,9 @@ const DeployToLocal = () => {
|
||||
.min(0, t("domain.deployment.form.file_key_path.placeholder"))
|
||||
.max(255, t("common.errmsg.string_max", { max: 255 })),
|
||||
pfxPassword: z.string().optional(),
|
||||
jksAlias: z.string().optional(),
|
||||
jksKeypass: z.string().optional(),
|
||||
jksStorepass: z.string().optional(),
|
||||
shell: z.union([z.literal("sh"), z.literal("cmd"), z.literal("powershell")], {
|
||||
message: t("domain.deployment.form.shell.placeholder"),
|
||||
}),
|
||||
@@ -65,6 +71,18 @@ const DeployToLocal = () => {
|
||||
.refine((data) => (data.format === "pfx" ? !!data.pfxPassword?.trim() : true), {
|
||||
message: t("domain.deployment.form.file_pfx_password.placeholder"),
|
||||
path: ["pfxPassword"],
|
||||
})
|
||||
.refine((data) => (data.format === "jks" ? !!data.jksAlias?.trim() : true), {
|
||||
message: t("domain.deployment.form.file_jks_alias.placeholder"),
|
||||
path: ["jksAlias"],
|
||||
})
|
||||
.refine((data) => (data.format === "jks" ? !!data.jksKeypass?.trim() : true), {
|
||||
message: t("domain.deployment.form.file_jks_keypass.placeholder"),
|
||||
path: ["jksKeypass"],
|
||||
})
|
||||
.refine((data) => (data.format === "jks" ? !!data.jksStorepass?.trim() : true), {
|
||||
message: t("domain.deployment.form.file_jks_storepass.placeholder"),
|
||||
path: ["jksStorepass"],
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -72,8 +90,13 @@ const DeployToLocal = () => {
|
||||
if (!res.success) {
|
||||
setError({
|
||||
...error,
|
||||
format: res.error.errors.find((e) => e.path[0] === "format")?.message,
|
||||
certPath: res.error.errors.find((e) => e.path[0] === "certPath")?.message,
|
||||
keyPath: res.error.errors.find((e) => e.path[0] === "keyPath")?.message,
|
||||
pfxPassword: res.error.errors.find((e) => e.path[0] === "pfxPassword")?.message,
|
||||
jksAlias: res.error.errors.find((e) => e.path[0] === "jksAlias")?.message,
|
||||
jksKeypass: res.error.errors.find((e) => e.path[0] === "jksKeypass")?.message,
|
||||
jksStorepass: res.error.errors.find((e) => e.path[0] === "jksStorepass")?.message,
|
||||
shell: res.error.errors.find((e) => e.path[0] === "shell")?.message,
|
||||
preCommand: res.error.errors.find((e) => e.path[0] === "preCommand")?.message,
|
||||
command: res.error.errors.find((e) => e.path[0] === "command")?.message,
|
||||
@@ -81,8 +104,13 @@ const DeployToLocal = () => {
|
||||
} else {
|
||||
setError({
|
||||
...error,
|
||||
format: undefined,
|
||||
certPath: undefined,
|
||||
keyPath: undefined,
|
||||
pfxPassword: undefined,
|
||||
jksAlias: undefined,
|
||||
jksKeypass: undefined,
|
||||
jksStorepass: undefined,
|
||||
shell: undefined,
|
||||
preCommand: undefined,
|
||||
command: undefined,
|
||||
@@ -92,18 +120,26 @@ const DeployToLocal = () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (data.config?.format === "pem") {
|
||||
if (data.config.certPath && data.config.certPath.endsWith(".pfx")) {
|
||||
if (/(.pfx|.jks)$/.test(data.config.certPath)) {
|
||||
const newData = produce(data, (draft) => {
|
||||
draft.config ??= {};
|
||||
draft.config.certPath = data.config!.certPath.replace(/.pfx$/, ".crt");
|
||||
draft.config.certPath = data.config!.certPath.replace(/(.pfx|.jks)$/, ".crt");
|
||||
});
|
||||
setDeploy(newData);
|
||||
}
|
||||
} else if (data.config?.format === "pfx") {
|
||||
if (data.config.certPath && data.config.certPath.endsWith(".crt")) {
|
||||
if (/(.crt|.jks)$/.test(data.config.certPath)) {
|
||||
const newData = produce(data, (draft) => {
|
||||
draft.config ??= {};
|
||||
draft.config.certPath = data.config!.certPath.replace(/.crt$/, ".pfx");
|
||||
draft.config.certPath = data.config!.certPath.replace(/(.crt|.jks)$/, ".pfx");
|
||||
});
|
||||
setDeploy(newData);
|
||||
}
|
||||
} else if (data.config?.format === "jks") {
|
||||
if (/(.crt|.pfx)$/.test(data.config.certPath)) {
|
||||
const newData = produce(data, (draft) => {
|
||||
draft.config ??= {};
|
||||
draft.config.certPath = data.config!.certPath.replace(/(.crt|.pfx)$/, ".jks");
|
||||
});
|
||||
setDeploy(newData);
|
||||
}
|
||||
@@ -194,6 +230,7 @@ Remove-Item -Path "$pfxPath" -Force
|
||||
<SelectGroup>
|
||||
<SelectItem value="pem">PEM</SelectItem>
|
||||
<SelectItem value="pfx">PFX</SelectItem>
|
||||
<SelectItem value="jks">JKS</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
@@ -259,6 +296,63 @@ Remove-Item -Path "$pfxPath" -Force
|
||||
<></>
|
||||
)}
|
||||
|
||||
{data.config?.format === "jks" ? (
|
||||
<>
|
||||
<div>
|
||||
<Label>{t("domain.deployment.form.file_jks_alias.label")}</Label>
|
||||
<Input
|
||||
placeholder={t("domain.deployment.form.file_jks_alias.placeholder")}
|
||||
className="w-full mt-1"
|
||||
value={data?.config?.jksAlias}
|
||||
onChange={(e) => {
|
||||
const newData = produce(data, (draft) => {
|
||||
draft.config ??= {};
|
||||
draft.config.jksAlias = e.target.value?.trim();
|
||||
});
|
||||
setDeploy(newData);
|
||||
}}
|
||||
/>
|
||||
<div className="text-red-600 text-sm mt-1">{error?.jksAlias}</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>{t("domain.deployment.form.file_jks_keypass.label")}</Label>
|
||||
<Input
|
||||
placeholder={t("domain.deployment.form.file_jks_keypass.placeholder")}
|
||||
className="w-full mt-1"
|
||||
value={data?.config?.jksKeypass}
|
||||
onChange={(e) => {
|
||||
const newData = produce(data, (draft) => {
|
||||
draft.config ??= {};
|
||||
draft.config.jksKeypass = e.target.value?.trim();
|
||||
});
|
||||
setDeploy(newData);
|
||||
}}
|
||||
/>
|
||||
<div className="text-red-600 text-sm mt-1">{error?.jksKeypass}</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>{t("domain.deployment.form.file_jks_storepass.label")}</Label>
|
||||
<Input
|
||||
placeholder={t("domain.deployment.form.file_jks_storepass.placeholder")}
|
||||
className="w-full mt-1"
|
||||
value={data?.config?.jksStorepass}
|
||||
onChange={(e) => {
|
||||
const newData = produce(data, (draft) => {
|
||||
draft.config ??= {};
|
||||
draft.config.jksStorepass = e.target.value?.trim();
|
||||
});
|
||||
setDeploy(newData);
|
||||
}}
|
||||
/>
|
||||
<div className="text-red-600 text-sm mt-1">{error?.jksStorepass}</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<Label>{t("domain.deployment.form.shell.label")}</Label>
|
||||
<RadioGroup
|
||||
|
||||
@@ -23,6 +23,9 @@ const DeployToSSH = () => {
|
||||
certPath: "/etc/nginx/ssl/nginx.crt",
|
||||
keyPath: "/etc/nginx/ssl/nginx.key",
|
||||
pfxPassword: "",
|
||||
jksAlias: "",
|
||||
jksKeypass: "",
|
||||
jksStorepass: "",
|
||||
preCommand: "",
|
||||
command: "sudo service nginx reload",
|
||||
},
|
||||
@@ -36,7 +39,7 @@ const DeployToSSH = () => {
|
||||
|
||||
const formSchema = z
|
||||
.object({
|
||||
format: z.union([z.literal("pem"), z.literal("pfx")], {
|
||||
format: z.union([z.literal("pem"), z.literal("pfx"), z.literal("jks")], {
|
||||
message: t("domain.deployment.form.file_format.placeholder"),
|
||||
}),
|
||||
certPath: z
|
||||
@@ -48,6 +51,9 @@ const DeployToSSH = () => {
|
||||
.min(0, t("domain.deployment.form.file_key_path.placeholder"))
|
||||
.max(255, t("common.errmsg.string_max", { max: 255 })),
|
||||
pfxPassword: z.string().optional(),
|
||||
jksAlias: z.string().optional(),
|
||||
jksKeypass: z.string().optional(),
|
||||
jksStorepass: z.string().optional(),
|
||||
preCommand: z.string().optional(),
|
||||
command: z.string().optional(),
|
||||
})
|
||||
@@ -58,6 +64,18 @@ const DeployToSSH = () => {
|
||||
.refine((data) => (data.format === "pfx" ? !!data.pfxPassword?.trim() : true), {
|
||||
message: t("domain.deployment.form.file_pfx_password.placeholder"),
|
||||
path: ["pfxPassword"],
|
||||
})
|
||||
.refine((data) => (data.format === "jks" ? !!data.jksAlias?.trim() : true), {
|
||||
message: t("domain.deployment.form.file_jks_alias.placeholder"),
|
||||
path: ["jksAlias"],
|
||||
})
|
||||
.refine((data) => (data.format === "jks" ? !!data.jksKeypass?.trim() : true), {
|
||||
message: t("domain.deployment.form.file_jks_keypass.placeholder"),
|
||||
path: ["jksKeypass"],
|
||||
})
|
||||
.refine((data) => (data.format === "jks" ? !!data.jksStorepass?.trim() : true), {
|
||||
message: t("domain.deployment.form.file_jks_storepass.placeholder"),
|
||||
path: ["jksStorepass"],
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -65,16 +83,26 @@ const DeployToSSH = () => {
|
||||
if (!res.success) {
|
||||
setError({
|
||||
...error,
|
||||
format: res.error.errors.find((e) => e.path[0] === "format")?.message,
|
||||
certPath: res.error.errors.find((e) => e.path[0] === "certPath")?.message,
|
||||
keyPath: res.error.errors.find((e) => e.path[0] === "keyPath")?.message,
|
||||
pfxPassword: res.error.errors.find((e) => e.path[0] === "pfxPassword")?.message,
|
||||
jksAlias: res.error.errors.find((e) => e.path[0] === "jksAlias")?.message,
|
||||
jksKeypass: res.error.errors.find((e) => e.path[0] === "jksKeypass")?.message,
|
||||
jksStorepass: res.error.errors.find((e) => e.path[0] === "jksStorepass")?.message,
|
||||
preCommand: res.error.errors.find((e) => e.path[0] === "preCommand")?.message,
|
||||
command: res.error.errors.find((e) => e.path[0] === "command")?.message,
|
||||
});
|
||||
} else {
|
||||
setError({
|
||||
...error,
|
||||
format: undefined,
|
||||
certPath: undefined,
|
||||
keyPath: undefined,
|
||||
pfxPassword: undefined,
|
||||
jksAlias: undefined,
|
||||
jksKeypass: undefined,
|
||||
jksStorepass: undefined,
|
||||
preCommand: undefined,
|
||||
command: undefined,
|
||||
});
|
||||
@@ -83,18 +111,26 @@ const DeployToSSH = () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (data.config?.format === "pem") {
|
||||
if (data.config.certPath && data.config.certPath.endsWith(".pfx")) {
|
||||
if (/(.pfx|.jks)$/.test(data.config.certPath)) {
|
||||
const newData = produce(data, (draft) => {
|
||||
draft.config ??= {};
|
||||
draft.config.certPath = data.config!.certPath.replace(/.pfx$/, ".crt");
|
||||
draft.config.certPath = data.config!.certPath.replace(/(.pfx|.jks)$/, ".crt");
|
||||
});
|
||||
setDeploy(newData);
|
||||
}
|
||||
} else if (data.config?.format === "pfx") {
|
||||
if (data.config.certPath && data.config.certPath.endsWith(".crt")) {
|
||||
if (/(.crt|.jks)$/.test(data.config.certPath)) {
|
||||
const newData = produce(data, (draft) => {
|
||||
draft.config ??= {};
|
||||
draft.config.certPath = data.config!.certPath.replace(/.crt$/, ".pfx");
|
||||
draft.config.certPath = data.config!.certPath.replace(/(.crt|.jks)$/, ".pfx");
|
||||
});
|
||||
setDeploy(newData);
|
||||
}
|
||||
} else if (data.config?.format === "jks") {
|
||||
if (/(.crt|.pfx)$/.test(data.config.certPath)) {
|
||||
const newData = produce(data, (draft) => {
|
||||
draft.config ??= {};
|
||||
draft.config.certPath = data.config!.certPath.replace(/(.crt|.pfx)$/, ".jks");
|
||||
});
|
||||
setDeploy(newData);
|
||||
}
|
||||
@@ -123,6 +159,7 @@ const DeployToSSH = () => {
|
||||
<SelectGroup>
|
||||
<SelectItem value="pem">PEM</SelectItem>
|
||||
<SelectItem value="pfx">PFX</SelectItem>
|
||||
<SelectItem value="jks">JKS</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
@@ -188,6 +225,63 @@ const DeployToSSH = () => {
|
||||
<></>
|
||||
)}
|
||||
|
||||
{data.config?.format === "jks" ? (
|
||||
<>
|
||||
<div>
|
||||
<Label>{t("domain.deployment.form.file_jks_alias.label")}</Label>
|
||||
<Input
|
||||
placeholder={t("domain.deployment.form.file_jks_alias.placeholder")}
|
||||
className="w-full mt-1"
|
||||
value={data?.config?.jksAlias}
|
||||
onChange={(e) => {
|
||||
const newData = produce(data, (draft) => {
|
||||
draft.config ??= {};
|
||||
draft.config.jksAlias = e.target.value?.trim();
|
||||
});
|
||||
setDeploy(newData);
|
||||
}}
|
||||
/>
|
||||
<div className="text-red-600 text-sm mt-1">{error?.jksAlias}</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>{t("domain.deployment.form.file_jks_keypass.label")}</Label>
|
||||
<Input
|
||||
placeholder={t("domain.deployment.form.file_jks_keypass.placeholder")}
|
||||
className="w-full mt-1"
|
||||
value={data?.config?.jksKeypass}
|
||||
onChange={(e) => {
|
||||
const newData = produce(data, (draft) => {
|
||||
draft.config ??= {};
|
||||
draft.config.jksKeypass = e.target.value?.trim();
|
||||
});
|
||||
setDeploy(newData);
|
||||
}}
|
||||
/>
|
||||
<div className="text-red-600 text-sm mt-1">{error?.jksKeypass}</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>{t("domain.deployment.form.file_jks_storepass.label")}</Label>
|
||||
<Input
|
||||
placeholder={t("domain.deployment.form.file_jks_storepass.placeholder")}
|
||||
className="w-full mt-1"
|
||||
value={data?.config?.jksStorepass}
|
||||
onChange={(e) => {
|
||||
const newData = produce(data, (draft) => {
|
||||
draft.config ??= {};
|
||||
draft.config.jksStorepass = e.target.value?.trim();
|
||||
});
|
||||
setDeploy(newData);
|
||||
}}
|
||||
/>
|
||||
<div className="text-red-600 text-sm mt-1">{error?.jksStorepass}</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<Label>{t("domain.deployment.form.shell_pre_command.label")}</Label>
|
||||
<Textarea
|
||||
|
||||
@@ -128,6 +128,12 @@
|
||||
"domain.deployment.form.file_key_path.placeholder": "Please enter private key save path",
|
||||
"domain.deployment.form.file_pfx_password.label": "PFX Output Password",
|
||||
"domain.deployment.form.file_pfx_password.placeholder": "Please enter PFX output password",
|
||||
"domain.deployment.form.file_jks_alias.label": "JKS Alias (KeyStore Alias)",
|
||||
"domain.deployment.form.file_jks_alias.placeholder": "Please enter JKS alias",
|
||||
"domain.deployment.form.file_jks_keypass.label": "JKS Key Password (KeyStore Keypass)",
|
||||
"domain.deployment.form.file_jks_keypass.placeholder": "Please enter JKS key password",
|
||||
"domain.deployment.form.file_jks_storepass.label": "JKS Store Password (KeyStore Storepass)",
|
||||
"domain.deployment.form.file_jks_storepass.placeholder": "Please enter JKS store password",
|
||||
"domain.deployment.form.shell.label": "Shell",
|
||||
"domain.deployment.form.shell.placeholder": "Please select shell environment",
|
||||
"domain.deployment.form.shell.option.sh.label": "POSIX Bash (Linux)",
|
||||
|
||||
@@ -128,6 +128,12 @@
|
||||
"domain.deployment.form.file_key_path.placeholder": "请输入私钥保存路径",
|
||||
"domain.deployment.form.file_pfx_password.label": "PFX 导出密码",
|
||||
"domain.deployment.form.file_pfx_password.placeholder": "请输入 PFX 导出密码",
|
||||
"domain.deployment.form.file_jks_alias.label": "JKS 别名(KeyStore Alias)",
|
||||
"domain.deployment.form.file_jks_alias.placeholder": "请输入 JKS 别名",
|
||||
"domain.deployment.form.file_jks_keypass.label": "JKS 私钥访问口令(KeyStore Keypass)",
|
||||
"domain.deployment.form.file_jks_keypass.placeholder": "请输入 JKS 私钥访问口令",
|
||||
"domain.deployment.form.file_jks_storepass.label": "JKS 密钥库存储口令(KeyStore Storepass)",
|
||||
"domain.deployment.form.file_jks_storepass.placeholder": "请输入 JKS 密钥库存储口令",
|
||||
"domain.deployment.form.shell.label": "Shell",
|
||||
"domain.deployment.form.shell.placeholder": "请选择命令执行环境",
|
||||
"domain.deployment.form.shell_pre_command.label": "前置命令",
|
||||
|
||||
Reference in New Issue
Block a user