Compare commits

..

24 Commits

Author SHA1 Message Date
Yoan.liu
65b199d392 update to version v0.3.4 2025-03-14 11:25:58 +08:00
Yoan.liu
dc0b86281e Merge pull request #517 from fudiwei/main
bugfix
2025-03-14 07:11:00 +08:00
Yoan.liu
b8796991b5 Merge pull request #518 from usual2970/hotfix/display
解决分支过多内容展示不完整的问题
2025-03-14 07:10:13 +08:00
Yoan.liu
83447fff62 fix the issue where content is not fully displayed when there are too many branches. 2025-03-13 17:22:34 +08:00
Fu Diwei
4a02c252d5 feat(ui): auto complete tencentcloud ssl deploy resource type 2025-03-13 16:20:03 +08:00
Fu Diwei
cb88df04b0 fix: #516 2025-03-13 16:03:35 +08:00
Yoan.liu
e888df2b9f Merge pull request #515 from fudiwei/main
enhance & bugfix
2025-03-12 21:44:12 +08:00
Fu Diwei
17af07e4bb feat: support sni on deployment to aliyun waf 2025-03-12 19:58:58 +08:00
Fu Diwei
d1aed36154 fix: #512 2025-03-12 19:36:14 +08:00
Fu Diwei
eb97f7a661 refactor: clean code 2025-03-12 16:56:02 +08:00
Yoan.liu
be822ccc93 update readme 2025-03-12 16:55:33 +08:00
Yoan.liu
e2b52eed61 Merge pull request #511 from LeoChen98/feat-rdp-preset
add feat: Windows RDP binding preset
2025-03-11 22:15:36 +08:00
Leo Chen
21717985ac add feat: Windows RDP binding preset 2025-03-11 21:38:22 +08:00
Yoan.liu
3c4ffee7d3 Update push_image.yml 2025-03-11 06:35:41 +08:00
Yoan.liu
3e1a457609 update to version v0.3.3 2025-03-10 21:33:06 +08:00
Yoan.liu
b28f0dc5e4 Merge pull request #504 from fudiwei/main
bugfix
2025-03-10 21:15:23 +08:00
Yoan.liu
29561ed75d Merge pull request #505 from usual2970/feat/image_tags
镜像增加大版本 tag
2025-03-10 21:14:47 +08:00
Yoan.liu
2e931d1f67 when tagging the image, also tag the major version 2025-03-10 16:33:28 +08:00
Fu Diwei
c907f22275 fix: wrong detection results of certificate key algorithm 2025-03-10 16:18:30 +08:00
Fu Diwei
19ccac5c05 build: set timezone in docker-compose 2025-03-10 15:22:25 +08:00
Fu Diwei
f9e3797cdd feat: default set autoRestart on deployment to 1panel or baotapanel 2025-03-10 15:13:41 +08:00
RHQYZ
a30379bfdb Merge branch 'usual2970:main' into main 2025-03-10 13:48:47 +08:00
Fu Diwei
643e09a4e6 fix: typo 2025-03-09 13:04:27 +08:00
Fu Diwei
56fc2d8b44 fix: invalid version checker 2025-03-09 12:57:01 +08:00
20 changed files with 238 additions and 70 deletions

View File

@@ -34,6 +34,11 @@ jobs:
images: |
usual2970/certimate
registry.cn-shanghai.aliyuncs.com/usual2970/certimate
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern=v{{version}}
type=semver,pattern=v{{major}}.{{minor}}
- name: Log in to DOCKERHUB
uses: docker/login-action@v3
@@ -56,3 +61,4 @@ jobs:
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}

View File

@@ -71,6 +71,7 @@ Certimate 旨在为用户提供一个安全、简便的 SSL 证书管理解决
相关文章:
- [使用 CNAME 实现 DNS-01 challenge](https://docs.certimate.me/blog/cname)
- [v0.3.0:第二个不向后兼容的大版本](https://docs.certimate.me/blog/v0.3.0)
- [v0.2.0:第一个不向后兼容的大版本](https://docs.certimate.me/blog/v0.2.0)
- [Why Certimate?](https://docs.certimate.me/blog/why-certimate)

View File

@@ -69,6 +69,7 @@ Please visit the documentation site [docs.certimate.me](https://docs.certimate.m
Related articles:
- [使用 CNAME 实现 DNS-01 challenge](https://docs.certimate.me/blog/cname)
- [v0.3.0:第二个不向后兼容的大版本](https://docs.certimate.me/blog/v0.3.0)
- [v0.2.0:第一个不向后兼容的大版本](https://docs.certimate.me/blog/v0.2.0)
- [Why Certimate?](https://docs.certimate.me/blog/why-certimate)

View File

@@ -6,5 +6,7 @@ services:
ports:
- 8090:8090
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- ./data:/app/pb_data
restart: unless-stopped

View File

@@ -226,6 +226,7 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) {
AccessKeySecret: access.AccessKeySecret,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
InstanceId: maps.GetValueAsString(options.ProviderDeployConfig, "instanceId"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
})
return deployer, err

View File

@@ -1,7 +1,10 @@
package domain
import (
"crypto/ecdsa"
"crypto/rsa"
"crypto/x509"
"fmt"
"strings"
"time"
@@ -39,19 +42,58 @@ func (c *Certificate) PopulateFromX509(certX509 *x509.Certificate) *Certificate
c.EffectAt = certX509.NotBefore
c.ExpireAt = certX509.NotAfter
switch certX509.SignatureAlgorithm {
case x509.SHA256WithRSA, x509.SHA256WithRSAPSS:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeRSA2048
case x509.SHA384WithRSA, x509.SHA384WithRSAPSS:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeRSA3072
case x509.SHA512WithRSA, x509.SHA512WithRSAPSS:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeRSA4096
case x509.ECDSAWithSHA256:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeEC256
case x509.ECDSAWithSHA384:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeEC384
case x509.ECDSAWithSHA512:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeEC512
switch certX509.PublicKeyAlgorithm {
case x509.RSA:
{
len := 0
if pubkey, ok := certX509.PublicKey.(*rsa.PublicKey); ok {
len = pubkey.N.BitLen()
}
switch len {
case 0:
c.KeyAlgorithm = CertificateKeyAlgorithmType("RSA")
case 2048:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeRSA2048
case 3072:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeRSA3072
case 4096:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeRSA4096
case 8192:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeRSA8192
default:
c.KeyAlgorithm = CertificateKeyAlgorithmType(fmt.Sprintf("RSA%d", len))
}
}
case x509.ECDSA:
{
len := 0
if pubkey, ok := certX509.PublicKey.(*ecdsa.PublicKey); ok {
if pubkey.Curve != nil && pubkey.Curve.Params() != nil {
len = pubkey.Curve.Params().BitSize
}
}
switch len {
case 0:
c.KeyAlgorithm = CertificateKeyAlgorithmType("EC")
case 256:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeEC256
case 384:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeEC384
case 521:
c.KeyAlgorithm = CertificateKeyAlgorithmTypeEC512
default:
c.KeyAlgorithm = CertificateKeyAlgorithmType(fmt.Sprintf("EC%d", len))
}
}
case x509.Ed25519:
{
c.KeyAlgorithm = CertificateKeyAlgorithmType("ED25519")
}
default:
c.KeyAlgorithm = CertificateKeyAlgorithmType("")
}

View File

@@ -62,14 +62,14 @@ type WorkflowNode struct {
}
type WorkflowNodeConfigForApply struct {
Domains string `json:"domains"` // 域名列表,以半角号分隔
Domains string `json:"domains"` // 域名列表,以半角号分隔
ContactEmail string `json:"contactEmail"` // 联系邮箱
ChallengeType string `json:"challengeType"` // TODO: 验证方式。目前仅支持 dns-01
Provider string `json:"provider"` // DNS 提供商
ProviderAccessId string `json:"providerAccessId"` // DNS 提供商授权记录 ID
ProviderConfig map[string]any `json:"providerConfig"` // DNS 提供商额外配置
KeyAlgorithm string `json:"keyAlgorithm"` // 密钥算法
Nameservers string `json:"nameservers"` // DNS 服务器列表,以半角号分隔
Nameservers string `json:"nameservers"` // DNS 服务器列表,以半角号分隔
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout"` // DNS 传播超时时间(零值取决于提供商的默认值)
DnsTTL int32 `json:"dnsTTL"` // DNS TTL零值取决于提供商的默认值
DisableFollowCNAME bool `json:"disableFollowCNAME"` // 是否关闭 CNAME 跟随

View File

@@ -297,7 +297,9 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
var errs []error
for _, listenerCertificate := range listenerCertificates {
if *listenerCertificate.CertificateId == cloudCertId {
// 监听证书 ID 格式:${证书 ID}-${地域}
certificateId := strings.Split(*listenerCertificate.CertificateId, "-")[0]
if certificateId == cloudCertId {
certificateIsAssociated = true
continue
}
@@ -306,14 +308,14 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
continue
}
listenerCertificateId, err := strconv.ParseInt(*listenerCertificate.CertificateId, 10, 64)
certificateIdAsInt64, err := strconv.ParseInt(certificateId, 10, 64)
if err != nil {
errs = append(errs, err)
continue
}
getUserCertificateDetailReq := &aliyunCas.GetUserCertificateDetailRequest{
CertId: tea.Int64(listenerCertificateId),
CertId: tea.Int64(certificateIdAsInt64),
}
getUserCertificateDetailResp, err := d.sdkClients.cas.GetUserCertificateDetail(getUserCertificateDetailReq)
if err != nil {
@@ -332,7 +334,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
continue
}
certificateIdsExpired = append(certificateIdsExpired, *listenerCertificate.CertificateId)
certificateIdsExpired = append(certificateIdsExpired, certificateId)
}
if len(errs) > 0 {

View File

@@ -24,8 +24,10 @@ type DeployerConfig struct {
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云地域。
Region string `json:"region"`
// 阿里云 WAF 实例 ID。
// WAF 实例 ID。
InstanceId string `json:"instanceId"`
// 接入域名(支持泛域名)。
Domain string `json:"domain,omitempty"`
}
type DeployerProvider struct {
@@ -74,38 +76,87 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Logt("certificate file uploaded", upres)
}
d.logger.Logt("certificate file uploaded", upres)
if d.config.Domain == "" {
// 未指定接入域名,只需替换默认证书即可
// 查询默认 SSL/TLS 设置
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedefaulthttps
describeDefaultHttpsReq := &aliyunWaf.DescribeDefaultHttpsRequest{
InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region),
}
describeDefaultHttpsResp, err := d.sdkClient.DescribeDefaultHttps(describeDefaultHttpsReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.DescribeDefaultHttps'")
}
// 查询默认 SSL/TLS 设置
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedefaulthttps
describeDefaultHttpsReq := &aliyunWaf.DescribeDefaultHttpsRequest{
InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region),
}
describeDefaultHttpsResp, err := d.sdkClient.DescribeDefaultHttps(describeDefaultHttpsReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.DescribeDefaultHttps'")
} else {
d.logger.Logt("已查询到默认 SSL/TLS 设置", describeDefaultHttpsResp)
}
d.logger.Logt("已查询到默认 SSL/TLS 设置", describeDefaultHttpsResp)
// 修改默认 SSL/TLS 设置
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-modifydefaulthttps
modifyDefaultHttpsReq := &aliyunWaf.ModifyDefaultHttpsRequest{
InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region),
CertId: tea.String(upres.CertId),
TLSVersion: tea.String("tlsv1"),
EnableTLSv3: tea.Bool(false),
}
if describeDefaultHttpsResp.Body != nil && describeDefaultHttpsResp.Body.DefaultHttps != nil {
modifyDefaultHttpsReq.TLSVersion = describeDefaultHttpsResp.Body.DefaultHttps.TLSVersion
modifyDefaultHttpsReq.EnableTLSv3 = describeDefaultHttpsResp.Body.DefaultHttps.EnableTLSv3
}
modifyDefaultHttpsResp, err := d.sdkClient.ModifyDefaultHttps(modifyDefaultHttpsReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.ModifyDefaultHttps'")
} else {
d.logger.Logt("已修改默认 SSL/TLS 设置", modifyDefaultHttpsResp)
}
} else {
// 指定接入域名
// 修改默认 SSL/TLS 设置
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-modifydefaulthttps
modifyDefaultHttpsReq := &aliyunWaf.ModifyDefaultHttpsRequest{
InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region),
CertId: tea.String(upres.CertId),
TLSVersion: describeDefaultHttpsResp.Body.DefaultHttps.TLSVersion,
EnableTLSv3: describeDefaultHttpsResp.Body.DefaultHttps.EnableTLSv3,
}
modifyDefaultHttpsResp, err := d.sdkClient.ModifyDefaultHttps(modifyDefaultHttpsReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.ModifyDefaultHttps'")
}
// 查询 CNAME 接入详情
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedomaindetail
describeDomainDetailReq := &aliyunWaf.DescribeDomainDetailRequest{
InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region),
Domain: tea.String(d.config.Domain),
}
describeDomainDetailResp, err := d.sdkClient.DescribeDomainDetail(describeDomainDetailReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.DescribeDomainDetail'")
} else {
d.logger.Logt("已查询到 CNAME 接入详情", describeDomainDetailResp)
}
d.logger.Logt("已修改默认 SSL/TLS 设置", modifyDefaultHttpsResp)
// 修改 CNAME 接入资源
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-modifydomain
modifyDomainReq := &aliyunWaf.ModifyDomainRequest{
InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region),
Domain: tea.String(d.config.Domain),
Listen: &aliyunWaf.ModifyDomainRequestListen{
CertId: tea.String(upres.CertId),
TLSVersion: tea.String("tlsv1"),
EnableTLSv3: tea.Bool(false),
},
Redirect: &aliyunWaf.ModifyDomainRequestRedirect{},
}
if describeDomainDetailResp.Body != nil && describeDomainDetailResp.Body.Listen != nil {
modifyDomainReq.Listen.TLSVersion = describeDomainDetailResp.Body.Listen.TLSVersion
modifyDomainReq.Listen.EnableTLSv3 = describeDomainDetailResp.Body.Listen.EnableTLSv3
modifyDomainReq.Listen.FocusHttps = describeDomainDetailResp.Body.Listen.FocusHttps
}
modifyDomainResp, err := d.sdkClient.ModifyDomain(modifyDomainReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.ModifyDomain'")
} else {
d.logger.Logt("已修改 CNAME 接入资源", modifyDomainResp)
}
}
return &deployer.DeployResult{}, nil
}

View File

@@ -104,19 +104,22 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
ServiceID: d.config.ServiceId,
},
UpdateHTTPSBody: &veImageX.UpdateHTTPSBody{
Domain: getDomainConfigResp.Result.Domain,
Domain: d.config.Domain,
HTTPS: &veImageX.UpdateHTTPSBodyHTTPS{
CertID: upres.CertId,
EnableHTTP2: getDomainConfigResp.Result.HTTPSConfig.EnableHTTP2,
EnableHTTPS: getDomainConfigResp.Result.HTTPSConfig.EnableHTTPS,
EnableOcsp: getDomainConfigResp.Result.HTTPSConfig.EnableOcsp,
TLSVersions: getDomainConfigResp.Result.HTTPSConfig.TLSVersions,
EnableForceRedirect: getDomainConfigResp.Result.HTTPSConfig.EnableForceRedirect,
ForceRedirectType: getDomainConfigResp.Result.HTTPSConfig.ForceRedirectType,
ForceRedirectCode: getDomainConfigResp.Result.HTTPSConfig.ForceRedirectCode,
CertID: upres.CertId,
EnableHTTPS: true,
},
},
}
if getDomainConfigResp.Result != nil && getDomainConfigResp.Result.HTTPSConfig != nil {
updateHttpsReq.UpdateHTTPSBody.HTTPS.EnableHTTPS = getDomainConfigResp.Result.HTTPSConfig.EnableHTTPS
updateHttpsReq.UpdateHTTPSBody.HTTPS.EnableHTTP2 = getDomainConfigResp.Result.HTTPSConfig.EnableHTTP2
updateHttpsReq.UpdateHTTPSBody.HTTPS.EnableOcsp = getDomainConfigResp.Result.HTTPSConfig.EnableOcsp
updateHttpsReq.UpdateHTTPSBody.HTTPS.TLSVersions = getDomainConfigResp.Result.HTTPSConfig.TLSVersions
updateHttpsReq.UpdateHTTPSBody.HTTPS.EnableForceRedirect = getDomainConfigResp.Result.HTTPSConfig.EnableForceRedirect
updateHttpsReq.UpdateHTTPSBody.HTTPS.ForceRedirectType = getDomainConfigResp.Result.HTTPSConfig.ForceRedirectType
updateHttpsReq.UpdateHTTPSBody.HTTPS.ForceRedirectCode = getDomainConfigResp.Result.HTTPSConfig.ForceRedirectCode
}
updateHttpsResp, err := d.sdkClient.UpdateHTTPS(context.TODO(), updateHttpsReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'imagex.UpdateHttps'")

View File

@@ -31,7 +31,7 @@ const WorkflowElements = ({ className, style, disabled }: WorkflowElementsProps)
return (
<div className={className} style={style}>
<div className="flex flex-col items-center overflow-auto">{elements}</div>
<div className="flex w-max min-w-full flex-col items-center">{elements}</div>
</div>
);
};

View File

@@ -16,7 +16,9 @@ export type DeployNodeConfigForm1PanelConsoleConfigProps = {
};
const initFormModel = (): DeployNodeConfigForm1PanelConsoleConfigFieldValues => {
return {};
return {
autoRestart: true,
};
};
const DeployNodeConfigForm1PanelConsoleConfig = ({

View File

@@ -3,9 +3,12 @@ import { Form, type FormInstance, Input } from "antd";
import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod";
import { validDomainName } from "@/utils/validators";
type DeployNodeConfigFormAliyunWAFConfigFieldValues = Nullish<{
region: string;
instanceId: string;
domain?: string;
}>;
export type DeployNodeConfigFormAliyunWAFConfigProps = {
@@ -39,6 +42,12 @@ const DeployNodeConfigFormAliyunWAFConfig = ({
.nonempty(t("workflow_node.deploy.form.aliyun_waf_instance_id.placeholder"))
.max(64, t("common.errmsg.string_max", { max: 64 }))
.trim(),
domain: z
.string()
.nullish()
.refine((v) => {
return !v || validDomainName(v!, { allowWildcard: true });
}, t("common.errmsg.domain_invalid")),
});
const formRule = createSchemaFieldRule(formSchema);
@@ -72,6 +81,15 @@ const DeployNodeConfigFormAliyunWAFConfig = ({
>
<Input placeholder={t("workflow_node.deploy.form.aliyun_waf_instance_id.placeholder")} />
</Form.Item>
<Form.Item
name="domain"
label={t("workflow_node.deploy.form.aliyun_waf_domain.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_waf_domain.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.aliyun_waf_domain.placeholder")} />
</Form.Item>
</Form>
);
};

View File

@@ -16,7 +16,9 @@ export type DeployNodeConfigFormBaotaPanelConsoleConfigProps = {
};
const initFormModel = (): DeployNodeConfigFormBaotaPanelConsoleConfigFieldValues => {
return {};
return {
autoRestart: true,
};
};
const DeployNodeConfigFormBaotaPanelConsoleConfig = ({

View File

@@ -138,14 +138,14 @@ const DeployNodeConfigFormLocalConfig = ({ form: formInst, formName, disabled, i
switch (key) {
case "reload_nginx":
{
formInst.setFieldValue("shellEnv", "sh");
formInst.setFieldValue("shellEnv", SHELLENV_SH);
formInst.setFieldValue("postCommand", "sudo service nginx reload");
}
break;
case "binding_iis":
{
formInst.setFieldValue("shellEnv", "powershell");
formInst.setFieldValue("shellEnv", SHELLENV_POWERSHELL);
formInst.setFieldValue(
"postCommand",
`# 请将以下变量替换为实际值
@@ -182,7 +182,7 @@ Remove-Item -Path "$pfxPath" -Force
case "binding_netsh":
{
formInst.setFieldValue("shellEnv", "powershell");
formInst.setFieldValue("shellEnv", SHELLENV_POWERSHELL);
formInst.setFieldValue(
"postCommand",
`# 请将以下变量替换为实际值
@@ -208,6 +208,26 @@ Remove-Item -Path "$pfxPath" -Force
);
}
break;
case "binding_rdp":
{
formInst.setFieldValue("shellEnv", SHELLENV_POWERSHELL);
formInst.setFieldValue(
"postCommand",
`# 请将以下变量替换为实际值
$pfxPath = "<your-pfx-path>" # PFX 文件路径
$pfxPassword = "<your-pfx-password>" # PFX 密码
# 导入证书到本地计算机的个人存储区
$cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable
# 获取 Thumbprint
$thumbprint = $cert.Thumbprint
# 绑定到 RDP
$rdpCertPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
Set-ItemProperty -Path $rdpCertPath -Name "SSLCertificateSHA1Hash" -Value "$thumbprint"
`.trim()
);
}
break;
}
};
@@ -341,6 +361,11 @@ Remove-Item -Path "$pfxPath" -Force
label: t("workflow_node.deploy.form.local_preset_scripts.option.binding_netsh.label"),
onClick: () => handlePresetScriptClick("binding_netsh"),
},
{
key: "binding_rdp",
label: t("workflow_node.deploy.form.local_preset_scripts.option.binding_rdp.label"),
onClick: () => handlePresetScriptClick("binding_rdp"),
},
],
}}
trigger={["click"]}

View File

@@ -1,7 +1,7 @@
import { memo } from "react";
import { useTranslation } from "react-i18next";
import { FormOutlined as FormOutlinedIcon } from "@ant-design/icons";
import { Alert, Button, Form, type FormInstance, Input, Space } from "antd";
import { Alert, AutoComplete, Button, Form, type FormInstance, Input, Space } from "antd";
import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod";
@@ -51,7 +51,7 @@ const DeployNodeConfigFormTencentCloudSSLDeployConfig = ({
if (!v) return false;
return String(v)
.split(MULTIPLE_INPUT_DELIMITER)
.every((e) => /^[A-Za-z0-9._-]+$/.test(e));
.every((e) => /^[A-Za-z0-9*._-]+$/.test(e));
}, t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.errmsg.invalid")),
});
const formRule = createSchemaFieldRule(formSchema);
@@ -86,7 +86,11 @@ const DeployNodeConfigFormTencentCloudSSLDeployConfig = ({
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_type.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_type.placeholder")} />
<AutoComplete
options={["apigateway", "cdn", "clb", "cos", "ddos", "lighthouse", "live", "tcb", "teo", "tke", "tse", "vod", "waf"].map((value) => ({ value }))}
placeholder={t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_type.placeholder")}
filterOption={(inputValue, option) => option!.value.toLowerCase().includes(inputValue.toLowerCase())}
/>
</Form.Item>
<Form.Item
@@ -131,7 +135,7 @@ const ResourceIdsModalInput = memo(({ value, trigger, onChange }: { value?: stri
const formSchema = z.object({
resourceIds: z.array(z.string()).refine((v) => {
return v.every((e) => !e?.trim() || /^[A-Za-z0-9._-]+$/.test(e));
return v.every((e) => !e?.trim() || /^[A-Za-z0-9*._-]+$/.test(e));
}, t("workflow_node.deploy.form.tencentcloud_ssl_deploy_resource_ids.errmsg.invalid")),
});
const formRule = createSchemaFieldRule(formSchema);

View File

@@ -1 +1 @@
export const version = "v0.3.2";
export const version = "v0.3.4";

View File

@@ -4,7 +4,7 @@ import { version } from "@/domain/version";
export type UseVersionCheckerReturns = {
hasNewVersion: boolean;
check: () => void;
checkNewVersion: () => void;
};
const extractSemver = (vers: string) => {
@@ -48,7 +48,7 @@ const useVersionChecker = () => {
}
const nIdx = releases.findIndex((e: any) => compareVersions(e.name, version) !== -1);
if (cIdx >= nIdx) {
if (cIdx !== -1 && cIdx <= nIdx) {
return false;
}
@@ -63,7 +63,7 @@ const useVersionChecker = () => {
return {
hasNewVersion: !!data,
check: refresh,
checkNewVersion: refresh,
};
};

View File

@@ -202,6 +202,9 @@
"workflow_node.deploy.form.aliyun_waf_instance_id.label": "Alibaba Cloud WAF instance ID",
"workflow_node.deploy.form.aliyun_waf_instance_id.placeholder": "Please enter Alibaba Cloud WAF instance ID",
"workflow_node.deploy.form.aliyun_waf_instance_id.tooltip": "For more information, see <a href=\"https://waf.console.aliyun.com\" target=\"_blank\">https://waf.console.aliyun.com</a>",
"workflow_node.deploy.form.aliyun_waf_domain.label": "Alibaba Cloud WAF domain (Optional)",
"workflow_node.deploy.form.aliyun_waf_domain.placeholder": "Please enter Alibaba Cloud WAF domain name",
"workflow_node.deploy.form.aliyun_waf_domain.tooltip": "For more information, see <a href=\"https://waf.console.aliyun.com\" target=\"_blank\">https://waf.console.aliyun.com</a>",
"workflow_node.deploy.form.aws_cloudfront_region.label": "AWS CloudFront Region",
"workflow_node.deploy.form.aws_cloudfront_region.placeholder": "Please enter AWS CloudFront region (e.g. us-east-1)",
"workflow_node.deploy.form.aws_cloudfront_region.tooltip": "For more information, see <a href=\"https://docs.aws.amazon.com/en_us/general/latest/gr/rande.html#regional-endpoints\" target=\"_blank\">https://docs.aws.amazon.com/en_us/general/latest/gr/rande.html#regional-endpoints</a>",
@@ -361,6 +364,7 @@
"workflow_node.deploy.form.local_preset_scripts.option.reload_nginx.label": "POSIX Bash - Reload nginx",
"workflow_node.deploy.form.local_preset_scripts.option.binding_iis.label": "PowerShell - Binding IIS",
"workflow_node.deploy.form.local_preset_scripts.option.binding_netsh.label": "PowerShell - Binding netsh",
"workflow_node.deploy.form.local_preset_scripts.option.binding_rdp.label": "PowerShell - Binding RDP",
"workflow_node.deploy.form.qiniu_cdn_domain.label": "Qiniu CDN domain",
"workflow_node.deploy.form.qiniu_cdn_domain.placeholder": "Please enter Qiniu CDN domain name",
"workflow_node.deploy.form.qiniu_cdn_domain.tooltip": "For more information, see <a href=\"https://portal.qiniu.com/cdn\" target=\"_blank\">https://portal.qiniu.com/cdn</a>",

View File

@@ -201,7 +201,10 @@
"workflow_node.deploy.form.aliyun_waf_region.tooltip": "这是什么?请参阅 <a href=\"https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-endpoint\" target=\"_blank\">https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-endpoint</a>",
"workflow_node.deploy.form.aliyun_waf_instance_id.label": "阿里云 WAF 实例 ID",
"workflow_node.deploy.form.aliyun_waf_instance_id.placeholder": "请输入阿里云 WAF 实例 ID",
"workflow_node.deploy.form.aliyun_waf_instance_id.tooltip": "这是什么?请参阅 <a href=\"https://waf.console.aliyun.com\" target=\"_blank\">https://waf.console.aliyun.com</a>",
"workflow_node.deploy.form.aliyun_waf_instance_id.tooltip": "这是什么?请参阅 <a href=\"https://waf.console.aliyun.com\" target=\"_blank\">https://waf.console.aliyun.com</a><br><br>仅支持 CNAME 接入。",
"workflow_node.deploy.form.aliyun_waf_domain.label": "阿里云 WAF 接入域名(可选)",
"workflow_node.deploy.form.aliyun_waf_domain.placeholder": "请输入阿里云 WAF 接入域名(支持泛域名)",
"workflow_node.deploy.form.aliyun_waf_domain.tooltip": "这是什么?请参阅 <a href=\"https://waf.console.aliyun.com\" target=\"_blank\">waf.console.aliyun.com</a><br><br>不填写时,将替换实例的默认证书。",
"workflow_node.deploy.form.aws_cloudfront_region.label": "AWS CloudFront 服务区域",
"workflow_node.deploy.form.aws_cloudfront_region.placeholder": "请输入 AWS CloudFront 服务区域例如us-east-1",
"workflow_node.deploy.form.aws_cloudfront_region.tooltip": "这是什么?请参阅 <a href=\"https://docs.aws.amazon.com/zh_cn/general/latest/gr/rande.html#regional-endpoints\" tworkflow_node.applyank\">https://docs.aws.amazon.com/zh_cn/general/latest/gr/rande.html#regional-endpoints</a>",
@@ -361,6 +364,7 @@
"workflow_node.deploy.form.local_preset_scripts.option.reload_nginx.label": "POSIX Bash - 重启 nginx 进程",
"workflow_node.deploy.form.local_preset_scripts.option.binding_iis.label": "PowerShell - 导入并绑定到 IIS需管理员权限",
"workflow_node.deploy.form.local_preset_scripts.option.binding_netsh.label": "PowerShell - 导入并绑定到 netsh需管理员权限",
"workflow_node.deploy.form.local_preset_scripts.option.binding_rdp.label": "PowerShell - 导入并绑定到 远程桌面连接(需管理员权限)",
"workflow_node.deploy.form.qiniu_cdn_domain.label": "七牛云 CDN 加速域名",
"workflow_node.deploy.form.qiniu_cdn_domain.placeholder": "请输入七牛云 CDN 加速域名(支持泛域名)",
"workflow_node.deploy.form.qiniu_cdn_domain.tooltip": "这是什么?请参阅 <a href=\"https://portal.qiniu.com/cdn\" target=\"_blank\">https://portal.qiniu.com/cdn</a>",