diff --git a/internal/web/actions/default/servers/index.go b/internal/web/actions/default/servers/index.go index bed36f40..7bafd4e7 100644 --- a/internal/web/actions/default/servers/index.go +++ b/internal/web/actions/default/servers/index.go @@ -120,8 +120,8 @@ func (this *IndexAction) RunGet(params struct { // 域名列表 serverNames := []*serverconfigs.ServerNameConfig{} - if len(server.ServerNamesJON) > 0 { - err = json.Unmarshal(server.ServerNamesJON, &serverNames) + if len(server.ServerNamesJSON) > 0 { + err = json.Unmarshal(server.ServerNamesJSON, &serverNames) if err != nil { this.ErrorPage(err) return diff --git a/internal/web/actions/default/servers/init.go b/internal/web/actions/default/servers/init.go index f68a2cd9..96461c89 100644 --- a/internal/web/actions/default/servers/init.go +++ b/internal/web/actions/default/servers/init.go @@ -11,7 +11,6 @@ func init() { server. Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)). Helper(NewHelper()). - Data("teaModule", "server"). Prefix("/servers"). Get("", new(IndexAction)). GetPost("/create", new(CreateAction)). diff --git a/internal/web/actions/default/servers/server/settings/https/init.go b/internal/web/actions/default/servers/server/settings/https/init.go index cca3f2c2..12d6dad9 100644 --- a/internal/web/actions/default/servers/server/settings/https/init.go +++ b/internal/web/actions/default/servers/server/settings/https/init.go @@ -14,6 +14,7 @@ func init() { Helper(serverutils.NewServerHelper()). Prefix("/servers/server/settings/https"). GetPost("", new(IndexAction)). + GetPost("/requestCertPopup", new(RequestCertPopupAction)). EndAll() }) } diff --git a/internal/web/actions/default/servers/server/settings/https/requestCertPopup.go b/internal/web/actions/default/servers/server/settings/https/requestCertPopup.go new file mode 100644 index 00000000..0b17aa63 --- /dev/null +++ b/internal/web/actions/default/servers/server/settings/https/requestCertPopup.go @@ -0,0 +1,176 @@ +package https + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dns/domains/domainutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" + "github.com/iwind/TeaGo/actions" + "github.com/iwind/TeaGo/lists" + "github.com/iwind/TeaGo/maps" + "strings" +) + +type RequestCertPopupAction struct { + actionutils.ParentAction +} + +func (this *RequestCertPopupAction) Init() { + this.Nav("", "", "") +} + +func (this *RequestCertPopupAction) RunGet(params struct { + ServerId int64 + ExcludeServerNames string +}) { + serverNamesResp, err := this.RPC().ServerRPC().FindServerNames(this.AdminContext(), &pb.FindServerNamesRequest{ServerId: params.ServerId}) + if err != nil { + this.ErrorPage(err) + return + } + + serverNameConfigs := []*serverconfigs.ServerNameConfig{} + err = json.Unmarshal(serverNamesResp.ServerNamesJSON, &serverNameConfigs) + if err != nil { + this.ErrorPage(err) + return + } + + excludeServerNames := []string{} + if len(params.ExcludeServerNames) > 0 { + excludeServerNames = strings.Split(params.ExcludeServerNames, ",") + } + serverNames := []string{} + for _, c := range serverNameConfigs { + if len(c.SubNames) == 0 { + if domainutils.ValidateDomainFormat(c.Name) && !lists.ContainsString(excludeServerNames, c.Name) { + serverNames = append(serverNames, c.Name) + } + } else { + for _, subName := range c.SubNames { + if domainutils.ValidateDomainFormat(subName) && !lists.ContainsString(excludeServerNames, subName) { + serverNames = append(serverNames, subName) + } + } + } + } + this.Data["serverNames"] = serverNames + + // 用户 + acmeUsersResp, err := this.RPC().ACMEUserRPC().FindAllACMEUsers(this.AdminContext(), &pb.FindAllACMEUsersRequest{ + AdminId: this.AdminId(), + UserId: 0, + }) + userMaps := []maps.Map{} + for _, user := range acmeUsersResp.AcmeUsers { + description := user.Description + if len(description) > 0 { + description = "(" + description + ")" + } + + userMaps = append(userMaps, maps.Map{ + "id": user.Id, + "description": description, + "email": user.Email, + }) + } + this.Data["users"] = userMaps + + this.Show() +} + +func (this *RequestCertPopupAction) RunPost(params struct { + ServerNames []string + + UserId int64 + UserEmail string + + Must *actions.Must + CSRF *actionutils.CSRF +}) { + // 检查域名 + if len(params.ServerNames) == 0 { + this.Fail("必须包含至少一个或多个域名") + } + + // 注册用户 + var acmeUserId int64 + if params.UserId > 0 { + // TODO 检查当前管理员是否可以使用此用户 + acmeUserId = params.UserId + } else if len(params.UserEmail) > 0 { + params.Must. + Field("userEmail", params.UserEmail). + Email("Email格式错误") + + createUserResp, err := this.RPC().ACMEUserRPC().CreateACMEUser(this.AdminContext(), &pb.CreateACMEUserRequest{ + Email: params.UserEmail, + Description: "", + }) + if err != nil { + this.ErrorPage(err) + return + } + defer this.CreateLogInfo("创建ACME用户", createUserResp.AcmeUserId) + acmeUserId = createUserResp.AcmeUserId + + this.Data["acmeUser"] = maps.Map{ + "id": acmeUserId, + "email": params.UserEmail, + } + } else { + this.Fail("请选择或者填写用户") + } + + createTaskResp, err := this.RPC().ACMETaskRPC().CreateACMETask(this.AdminContext(), &pb.CreateACMETaskRequest{ + AcmeUserId: acmeUserId, + DnsProviderId: 0, + DnsDomain: "", + Domains: params.ServerNames, + AutoRenew: true, + AuthType: "http", + }) + if err != nil { + this.ErrorPage(err) + return + } + + taskId := createTaskResp.AcmeTaskId + + defer this.CreateLogInfo("自动申请证书,任务 %d", taskId) + + runResp, err := this.RPC().ACMETaskRPC().RunACMETask(this.AdminContext(), &pb.RunACMETaskRequest{AcmeTaskId: taskId}) + if err != nil { + this.ErrorPage(err) + return + } + + if runResp.IsOk { + certId := runResp.SslCertId + + configResp, err := this.RPC().SSLCertRPC().FindEnabledSSLCertConfig(this.AdminContext(), &pb.FindEnabledSSLCertConfigRequest{CertId: certId}) + if err != nil { + this.ErrorPage(err) + return + } + certConfig := &sslconfigs.SSLCertConfig{} + err = json.Unmarshal(configResp.CertJSON, certConfig) + if err != nil { + this.ErrorPage(err) + return + } + certConfig.CertData = nil // 去掉不必要的数据 + certConfig.KeyData = nil // 去掉不必要的数据 + this.Data["cert"] = certConfig + this.Data["certRef"] = &sslconfigs.SSLCertRef{ + IsOn: true, + CertId: certId, + } + + this.Success() + } else { + this.Fail(runResp.Error) + } +} diff --git a/internal/web/actions/default/servers/server/settings/serverNames/index.go b/internal/web/actions/default/servers/server/settings/serverNames/index.go index f741ef26..065c50f6 100644 --- a/internal/web/actions/default/servers/server/settings/serverNames/index.go +++ b/internal/web/actions/default/servers/server/settings/serverNames/index.go @@ -28,8 +28,8 @@ func (this *IndexAction) RunGet(params struct { } serverNamesConfig := []*serverconfigs.ServerNameConfig{} - if len(server.ServerNamesJON) > 0 { - err := json.Unmarshal(server.ServerNamesJON, &serverNamesConfig) + if len(server.ServerNamesJSON) > 0 { + err := json.Unmarshal(server.ServerNamesJSON, &serverNamesConfig) if err != nil { this.ErrorPage(err) return diff --git a/web/public/js/components/server/ssl-certs-box.js b/web/public/js/components/server/ssl-certs-box.js index 208c43d8..6c11011e 100644 --- a/web/public/js/components/server/ssl-certs-box.js +++ b/web/public/js/components/server/ssl-certs-box.js @@ -1,10 +1,16 @@ Vue.component("ssl-certs-box", { - props: ["v-certs", "v-protocol", "v-view-size", "v-single-mode"], + props: [ + "v-certs", // 证书列表 + "v-protocol", // 协议:https|tls + "v-view-size", // 弹窗尺寸 + "v-single-mode" // 单证书模式 + ], data: function () { let certs = this.vCerts if (certs == null) { certs = [] } + return { certs: certs } @@ -82,7 +88,7 @@ Vue.component("ssl-certs-box", {