diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormLocalConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormLocalConfig.tsx index 700f0b09..75853eb7 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormLocalConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormLocalConfig.tsx @@ -52,6 +52,8 @@ export const initPresetScript = ( key: "sh_backup_files" | "ps_backup_files" | "sh_reload_nginx" | "ps_binding_iis" | "ps_binding_netsh" | "ps_binding_rdp", params?: { certPath?: string; + certPathForServerOnly?: string; + certPathForIntermediaOnly?: string; keyPath?: string; pfxPassword?: string; jksAlias?: string; @@ -77,19 +79,22 @@ if (Test-Path -Path "${params?.keyPath || ""}" -PathType Leaf) { `.trim(); case "sh_reload_nginx": - return `sudo service nginx reload`; + return `# *** 需要 root 权限 *** + +sudo service nginx reload + `.trim(); case "ps_binding_iis": - return `# 需要管理员权限 + return `# *** 需要管理员权限 *** + # 请将以下变量替换为实际值 -$pfxPath = "${params?.certPath || ""}" # PFX 文件路径 -$pfxPassword = "${params?.pfxPassword || ""}" # PFX 密码 +$pfxPath = "${params?.certPath || ""}" # PFX 文件路径(与表单中保持一致) +$pfxPassword = "${params?.pfxPassword || ""}" # PFX 密码(与表单中保持一致) $siteName = "" # IIS 网站名称 $domain = "" # 域名 $ipaddr = "" # 绑定 IP,“*”表示所有 IP 绑定 $port = "" # 绑定端口 - # 导入证书到本地计算机的个人存储区 $cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable # 获取 Thumbprint @@ -111,16 +116,16 @@ Remove-Item -Path "$pfxPath" -Force `.trim(); case "ps_binding_netsh": - return `# 需要管理员权限 + return `# *** 需要管理员权限 *** + # 请将以下变量替换为实际值 -$pfxPath = "${params?.certPath || ""}" # PFX 文件路径 -$pfxPassword = "${params?.pfxPassword || ""}" # PFX 密码 -$ipaddr = "" # 绑定 IP,“0.0.0.0”表示所有 IP 绑定,可填入域名。 +$pfxPath = "${params?.certPath || ""}" # PFX 文件路径(与表单中保持一致) +$pfxPassword = "${params?.pfxPassword || ""}" # PFX 密码(与表单中保持一致) +$ipaddr = "" # 绑定 IP,“0.0.0.0”表示所有 IP 绑定,可填入域名 $port = "" # 绑定端口 -$addr = $ipaddr + ":" + $port - # 导入证书到本地计算机的个人存储区 +$addr = $ipaddr + ":" + $port $cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable # 获取 Thumbprint $thumbprint = $cert.Thumbprint @@ -134,10 +139,11 @@ Remove-Item -Path "$pfxPath" -Force `.trim(); case "ps_binding_rdp": - return `# 需要管理员权限 + return `# *** 需要管理员权限 *** + # 请将以下变量替换为实际值 -$pfxPath = "${params?.certPath || ""}" # PFX 文件路径 -$pfxPassword = "${params?.pfxPassword || ""}" # PFX 密码 +$pfxPath = "${params?.certPath || ""}" # PFX 文件路径(与表单中保持一致) +$pfxPassword = "${params?.pfxPassword || ""}" # PFX 密码(与表单中保持一致) # 导入证书到本地计算机的个人存储区 $cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormSSHConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormSSHConfig.tsx index 6a8d01c9..0f3f3082 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormSSHConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormSSHConfig.tsx @@ -8,7 +8,7 @@ import CodeInput from "@/components/CodeInput"; import Show from "@/components/Show"; import { CERTIFICATE_FORMATS } from "@/domain/certificate"; -import { initPresetScript } from "./DeployNodeConfigFormLocalConfig"; +import { initPresetScript as _initPresetScript } from "./DeployNodeConfigFormLocalConfig"; type DeployNodeConfigFormSSHConfigFieldValues = Nullish<{ format: string; @@ -45,6 +45,126 @@ const initFormModel = (): DeployNodeConfigFormSSHConfigFieldValues => { }; }; +const initPresetScript = ( + key: Parameters[0] | "sh_replace_synologydsm_ssl" | "sh_replace_fnos_ssl", + params?: Parameters[1] +) => { + switch (key) { + case "sh_replace_synologydsm_ssl": + return `# *** 需要 root 权限 *** +# 脚本参考 https://github.com/catchdave/ssl-certs/blob/main/replace_synology_ssl_certs.sh + +# 请将以下变量替换为实际值 +$tmpFullchainPath = "${params?.certPath || ""}" # 证书文件路径(与表单中保持一致) +$tmpCertPath = "${params?.certPathForServerOnly || ""}" # 服务器证书文件路径(与表单中保持一致) +$tmpKeyPath = "${params?.keyPath || ""}" # 私钥文件路径(与表单中保持一致) + +DEBUG=1 +error_exit() { echo "[ERROR] $1"; exit 1; } +warn() { echo "[WARN] $1"; } +info() { echo "[INFO] $1"; } +debug() { [[ "\${DEBUG}" ]] && echo "[DEBUG] $1"; } + +certs_src_dir="/usr/syno/etc/certificate/system/default" +target_cert_dirs=( + "/usr/syno/etc/certificate/system/FQDN" + "/usr/local/etc/certificate/ScsiTarget/pkg-scsi-plugin-server/" + "/usr/local/etc/certificate/SynologyDrive/SynologyDrive/" + "/usr/local/etc/certificate/WebDAVServer/webdav/" + "/usr/local/etc/certificate/ActiveBackup/ActiveBackup/" + "/usr/syno/etc/certificate/smbftpd/ftpd/") + +# 获取证书目录 +default_dir_name=$(/dev/null && /usr/syno/bin/synopkg restart ScsiTarget +/usr/syno/bin/synopkg is_onoff SynologyDrive 1>/dev/null && /usr/syno/bin/synopkg restart SynologyDrive +/usr/syno/bin/synopkg is_onoff WebDAVServer 1>/dev/null && /usr/syno/bin/synopkg restart WebDAVServer +/usr/syno/bin/synopkg is_onoff ActiveBackup 1>/dev/null && /usr/syno/bin/synopkg restart ActiveBackup +if ! /usr/syno/bin/synow3tool --gen-all && sudo /usr/syno/bin/synosystemctl restart nginx; then + warn "nginx failed to restart" +fi + +info "Completed" + `.trim(); + + case "sh_replace_fnos_ssl": + return `# *** 需要 root 权限 *** +# 脚本参考 https://github.com/lfgyx/fnos_certificate_update/blob/main/src/update_cert.sh + + +# 请将以下变量替换为实际值 +# 飞牛证书实际存放路径请在 \`/usr/trim/etc/network_cert_all.conf\` 中查看,注意不要修改文件名 +$tmpFullchainPath = "${params?.certPath || ""}" # 证书文件路径(与表单中保持一致) +$tmpCertPath = "${params?.certPathForServerOnly || ""}" # 服务器证书文件路径(与表单中保持一致) +$tmpKeyPath = "${params?.keyPath || ""}" # 私钥文件路径(与表单中保持一致) +$fnFullchainPath = "/usr/trim/var/trim_connect/ssls/example.com/1234567890/fullchain.crt" # 飞牛证书文件路径 +$fnCertPath = "/usr/trim/var/trim_connect/ssls/example.com/1234567890/example.com.crt" # 飞牛服务器证书文件路径 +$fnKeyPath = "/usr/trim/var/trim_connect/ssls/example.com/1234567890/example.com.key" # 飞牛私钥文件路径 +$domain = "" # 域名 + +# 复制文件 +cp -rf "$tmpFullchainPath" "$fnFullchainPath" +cp -rf "$tmpCertPath" "$fnCertPath" +cp -rf "$tmpKeyPath" "$fnKeyPath" +chmod 755 "$fnCertPath" +chmod 755 "$fnKeyPath" +chmod 755 "$fnFullchainPath" + +# 更新数据库 +NEW_EXPIRY_DATE=$(openssl x509 -enddate -noout -in "$fnCertPath" | sed "s/^.*=\\(.*\\)$/\\1/") +NEW_EXPIRY_TIMESTAMP=$(date -d "$NEW_EXPIRY_DATE" +%s%3N) +psql -U postgres -d trim_connect -c "UPDATE cert SET valid_to=$NEW_EXPIRY_TIMESTAMP WHERE domain='$domain'" + +# 重启服务 +systemctl restart webdav.service +systemctl restart smbftpd.service +systemctl restart trim_nginx.service + `.trim(); + } + + return _initPresetScript(key as Parameters[0], params); +}; + const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: DeployNodeConfigFormSSHConfigProps) => { const { t } = useTranslation(); @@ -160,6 +280,24 @@ const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, ini const handlePresetPostScriptClick = (key: string) => { switch (key) { case "sh_reload_nginx": + { + formInst.setFieldValue("postCommand", initPresetScript(key)); + } + break; + + case "sh_replace_synologydsm_ssl": + case "sh_replace_fnos_ssl": + { + const presetScriptParams = { + certPath: formInst.getFieldValue("certPath"), + certPathForServerOnly: formInst.getFieldValue("certPathForServerOnly"), + certPathForIntermediaOnly: formInst.getFieldValue("certPathForIntermediaOnly"), + keyPath: formInst.getFieldValue("keyPath"), + }; + formInst.setFieldValue("postCommand", initPresetScript(key, presetScriptParams)); + } + break; + case "ps_binding_iis": case "ps_binding_netsh": case "ps_binding_rdp": @@ -324,11 +462,13 @@ const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, ini
({ - key, - label: t(`workflow_node.deploy.form.ssh_preset_scripts.option.${key}.label`), - onClick: () => handlePresetPostScriptClick(key), - })), + items: ["sh_reload_nginx", "sh_replace_synologydsm_ssl", "sh_replace_fnos_ssl", "ps_binding_iis", "ps_binding_netsh", "ps_binding_rdp"].map( + (key) => ({ + key, + label: t(`workflow_node.deploy.form.ssh_preset_scripts.option.${key}.label`), + onClick: () => handlePresetPostScriptClick(key), + }) + ), }} trigger={["click"]} > diff --git a/ui/src/i18n/locales/en/nls.access.json b/ui/src/i18n/locales/en/nls.access.json index 5a1c086c..d7dfd285 100644 --- a/ui/src/i18n/locales/en/nls.access.json +++ b/ui/src/i18n/locales/en/nls.access.json @@ -377,7 +377,7 @@ "access.form.webhook_default_data.errmsg.json_invalid": "Please enter a valiod JSON string", "access.form.webhook_default_data_for_deployment.label": "Webhook data for deployment (Optional)", "access.form.webhook_default_data_for_deployment.placeholder": "Please enter Webhook data", - "access.form.webhook_default_data_for_deployment.guide": "Tips: The Webhook data should be in JSON format.

The values in JSON support template variables, which will be replaced by actual values when sent to the Webhook URL. Supported variables:
  1. ${DOMAIN}: The primary domain of the certificate (CommonName).
  2. ${DOMAINS}: The domain list of the certificate (SubjectAltNames).
  3. ${CERTIFICATE}: The PEM format content of the certificate file.
  4. ${SERVER_CERTIFICATE}: The PEM format content of the server certificate file.
  5. ${INTERMEDIA_CERTIFICATE}: The PEM format content of the intermedia certificate file.
  6. ${PRIVATE_KEY}: The PEM format content of the private key file.

When the request method is GET, the data will be passed as query string. Otherwise, the data will be encoded in the format indicated by the Content-Type in the request headers. Supported formats:
  1. application/json (default).
  2. application/x-www-form-urlencoded: Nested data is not supported.
  3. multipart/form-data: Nested data is not supported.
  4. ", + "access.form.webhook_default_data_for_deployment.guide": "Tips: The Webhook data should be in JSON format.

    The values in JSON support template variables, which will be replaced by actual values when sent to the Webhook URL. Supported variables:
    1. ${DOMAIN}: The primary domain of the certificate (CommonName).
    2. ${DOMAINS}: The domain list of the certificate (SubjectAltNames).
    3. ${CERTIFICATE}: The PEM format content of the certificate file.
    4. ${SERVER_CERTIFICATE}: The PEM format content of the server certificate file.
    5. ${INTERMEDIA_CERTIFICATE}: The PEM format content of the intermediate CA certificate file.
    6. ${PRIVATE_KEY}: The PEM format content of the private key file.

    When the request method is GET, the data will be passed as query string. Otherwise, the data will be encoded in the format indicated by the Content-Type in the request headers. Supported formats:
    1. application/json (default).
    2. application/x-www-form-urlencoded: Nested data is not supported.
    3. multipart/form-data: Nested data is not supported.
    4. ", "access.form.webhook_default_data_for_notification.label": "Webhook data for notification (Optional)", "access.form.webhook_default_data_for_notification.placeholder": "Please enter Webhook data", "access.form.webhook_default_data_for_notification.guide": "Tips: The Webhook data should be in JSON format.

      The values in JSON support template variables, which will be replaced by actual values when sent to the Webhook URL. Supported variables:
      1. ${SUBJECT}: The subject of notification.
      2. ${MESSAGE}: The message of notification.

      When the request method is GET, the data will be passed as query string. Otherwise, the data will be encoded in the format indicated by the Content-Type in the request headers. Supported formats:
      1. application/json (default).
      2. application/x-www-form-urlencoded: Nested data is not supported.
      3. multipart/form-data: Nested data is not supported.
      4. ", diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index c16a48ca..cffba30d 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -455,8 +455,8 @@ "workflow_node.deploy.form.local_servercert_path.label": "Server certificate file saving path (Optional)", "workflow_node.deploy.form.local_servercert_path.placeholder": "Please enter saving path for server certificate file", "workflow_node.deploy.form.local_servercert_path.tooltip": "Note that the path should include the complete file name, not just the directory.", - "workflow_node.deploy.form.local_intermediacert_path.label": "Intermedia certificate file saving path (Optional)", - "workflow_node.deploy.form.local_intermediacert_path.placeholder": "Please enter saving path for intermedia certificate file", + "workflow_node.deploy.form.local_intermediacert_path.label": "Intermediate CA certificate file saving path (Optional)", + "workflow_node.deploy.form.local_intermediacert_path.placeholder": "Please enter saving path for intermediate CA certificate file", "workflow_node.deploy.form.local_intermediacert_path.tooltip": "Note that the path should include the complete file name, not just the directory.", "workflow_node.deploy.form.local_pfx_password.label": "PFX password", "workflow_node.deploy.form.local_pfx_password.placeholder": "Please enter PFX password", @@ -526,8 +526,8 @@ "workflow_node.deploy.form.ssh_servercert_path.label": "Server certificate file uploading path (Optional)", "workflow_node.deploy.form.ssh_servercert_path.placeholder": "Please enter uploading path for server certificate file", "workflow_node.deploy.form.ssh_servercert_path.tooltip": "Note that the path should include the complete file name, not just the directory.", - "workflow_node.deploy.form.ssh_intermediacert_path.label": "Intermedia certificate file uploading path (Optional)", - "workflow_node.deploy.form.ssh_intermediacert_path.placeholder": "Please enter uploading path for intermedia certificate file", + "workflow_node.deploy.form.ssh_intermediacert_path.label": "Intermediate CA certificate file uploading path (Optional)", + "workflow_node.deploy.form.ssh_intermediacert_path.placeholder": "Please enter uploading path for intermediate CA certificate file", "workflow_node.deploy.form.ssh_intermediacert_path.tooltip": "Note that the path should include the complete file name, not just the directory.", "workflow_node.deploy.form.ssh_pfx_password.label": "PFX password", "workflow_node.deploy.form.ssh_pfx_password.placeholder": "Please enter PFX password", @@ -549,6 +549,8 @@ "workflow_node.deploy.form.ssh_preset_scripts.option.sh_backup_files.label": "POSIX Bash - Backup certificate files", "workflow_node.deploy.form.ssh_preset_scripts.option.ps_backup_files.label": "PowerShell - Backup certificate files", "workflow_node.deploy.form.ssh_preset_scripts.option.sh_reload_nginx.label": "POSIX Bash - Reload nginx", + "workflow_node.deploy.form.ssh_preset_scripts.option.sh_replace_synologydsm_ssl.label": "POSIX Bash - Replace SynologyDSM SSL certificate", + "workflow_node.deploy.form.ssh_preset_scripts.option.sh_replace_fnos_ssl.label": "POSIX Bash - Replace fnOS SSL certificate", "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_iis.label": "PowerShell - Binding IIS", "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_netsh.label": "PowerShell - Binding netsh", "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_rdp.label": "PowerShell - Binding RDP", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 73fa56ad..378cff37 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -548,6 +548,8 @@ "workflow_node.deploy.form.ssh_preset_scripts.option.sh_backup_files.label": "POSIX Bash - 备份原证书文件", "workflow_node.deploy.form.ssh_preset_scripts.option.ps_backup_files.label": "PowerShell - 备份原证书文件", "workflow_node.deploy.form.ssh_preset_scripts.option.sh_reload_nginx.label": "POSIX Bash - 重启 nginx 进程", + "workflow_node.deploy.form.ssh_preset_scripts.option.sh_replace_synologydsm_ssl.label": "POSIX Bash - 替换群晖 DSM 证书", + "workflow_node.deploy.form.ssh_preset_scripts.option.sh_replace_fnos_ssl.label": "POSIX Bash - 替换飞牛 OS 证书", "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_iis.label": "PowerShell - 导入并绑定到 IIS", "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_netsh.label": "PowerShell - 导入并绑定到 netsh", "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_rdp.label": "PowerShell - 导入并绑定到 RDP",