mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 05:00:25 +08:00 
			
		
		
		
	ACME证书增加ZeroSSL支持
This commit is contained in:
		@@ -364,6 +364,14 @@ func (this *RPCClient) ACMETaskRPC() pb.ACMETaskServiceClient {
 | 
			
		||||
	return pb.NewACMETaskServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) ACMEProviderRPC() pb.ACMEProviderServiceClient {
 | 
			
		||||
	return pb.NewACMEProviderServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) ACMEProviderAccountRPC() pb.ACMEProviderAccountServiceClient {
 | 
			
		||||
	return pb.NewACMEProviderAccountServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) UserRPC() pb.UserServiceClient {
 | 
			
		||||
	return pb.NewUserServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,100 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package accounts
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type CreatePopupAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreatePopupAction) Init() {
 | 
			
		||||
	this.Nav("", "", "")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreatePopupAction) RunGet(params struct {
 | 
			
		||||
	ProviderCode string
 | 
			
		||||
}) {
 | 
			
		||||
	this.Data["providerCode"] = params.ProviderCode
 | 
			
		||||
 | 
			
		||||
	// 服务商列表
 | 
			
		||||
	providersResp, err := this.RPC().ACMEProviderRPC().FindAllACMEProviders(this.AdminContext(), &pb.FindAllACMEProvidersRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var providerMaps = []maps.Map{}
 | 
			
		||||
	for _, provider := range providersResp.AcmeProviders {
 | 
			
		||||
		providerMaps = append(providerMaps, maps.Map{
 | 
			
		||||
			"name":           provider.Name,
 | 
			
		||||
			"code":           provider.Code,
 | 
			
		||||
			"description":    provider.Description,
 | 
			
		||||
			"requireEAB":     provider.RequireEAB,
 | 
			
		||||
			"eabDescription": provider.EabDescription,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["providers"] = providerMaps
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreatePopupAction) RunPost(params struct {
 | 
			
		||||
	Name         string
 | 
			
		||||
	ProviderCode string
 | 
			
		||||
	EabKid       string
 | 
			
		||||
	EabKey       string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
}) {
 | 
			
		||||
	var accountId int64
 | 
			
		||||
	defer func() {
 | 
			
		||||
		this.CreateLogInfo("创建ACME服务商账号 %d", accountId)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	params.Must.
 | 
			
		||||
		Field("name", params.Name).
 | 
			
		||||
		Require("请输入账号名称").
 | 
			
		||||
		Field("providerCode", params.ProviderCode).
 | 
			
		||||
		Require("请选择服务商")
 | 
			
		||||
 | 
			
		||||
	providerResp, err := this.RPC().ACMEProviderRPC().FindACMEProviderWithCode(this.AdminContext(), &pb.FindACMEProviderWithCodeRequest{AcmeProviderCode: params.ProviderCode})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var provider = providerResp.AcmeProvider
 | 
			
		||||
	if provider == nil {
 | 
			
		||||
		this.Fail("请选择服务商")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if provider.RequireEAB {
 | 
			
		||||
		params.Must.
 | 
			
		||||
			Field("eabKid", params.EabKid).
 | 
			
		||||
			Require("请输入EAB Kid").
 | 
			
		||||
			Field("eabKey", params.EabKey).
 | 
			
		||||
			Require("请输入EAB HMAC Key")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	createResp, err := this.RPC().ACMEProviderAccountRPC().CreateACMEProviderAccount(this.AdminContext(), &pb.CreateACMEProviderAccountRequest{
 | 
			
		||||
		Name:         params.Name,
 | 
			
		||||
		ProviderCode: params.ProviderCode,
 | 
			
		||||
		EabKid:       params.EabKid,
 | 
			
		||||
		EabKey:       params.EabKey,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	accountId = createResp.AcmeProviderAccountId
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,26 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package accounts
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type DeleteAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *DeleteAction) RunPost(params struct {
 | 
			
		||||
	AccountId int64
 | 
			
		||||
}) {
 | 
			
		||||
	defer this.CreateLogInfo("删除ACME服务商账号 %d", params.AccountId)
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().ACMEProviderAccountRPC().DeleteACMEProviderAccount(this.AdminContext(), &pb.DeleteACMEProviderAccountRequest{AcmeProviderAccountId: params.AccountId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,61 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package accounts
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IndexAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "", "account")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
	countResp, err := this.RPC().ACMEProviderAccountRPC().CountAllEnabledACMEProviderAccounts(this.AdminContext(), &pb.CountAllEnabledACMEProviderAccountsRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var count = countResp.Count
 | 
			
		||||
	var page = this.NewPage(count)
 | 
			
		||||
	this.Data["page"] = page.AsHTML()
 | 
			
		||||
 | 
			
		||||
	accountsResp, err := this.RPC().ACMEProviderAccountRPC().ListEnabledACMEProviderAccounts(this.AdminContext(), &pb.ListEnabledACMEProviderAccountsRequest{
 | 
			
		||||
		Offset: page.Offset,
 | 
			
		||||
		Size:   page.Size,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var accountMaps = []maps.Map{}
 | 
			
		||||
	for _, account := range accountsResp.AcmeProviderAccounts {
 | 
			
		||||
		var providerMap maps.Map
 | 
			
		||||
		if account.AcmeProvider != nil {
 | 
			
		||||
			providerMap = maps.Map{
 | 
			
		||||
				"name":       account.AcmeProvider.Name,
 | 
			
		||||
				"code":       account.AcmeProvider.Code,
 | 
			
		||||
				"requireEAB": account.AcmeProvider.RequireEAB,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		accountMaps = append(accountMaps, maps.Map{
 | 
			
		||||
			"id":       account.Id,
 | 
			
		||||
			"isOn":     account.IsOn,
 | 
			
		||||
			"name":     account.Name,
 | 
			
		||||
			"eabKid":   account.EabKid,
 | 
			
		||||
			"eabKey":   account.EabKey,
 | 
			
		||||
			"provider": providerMap,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["accounts"] = accountMaps
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,108 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package accounts
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type UpdatePopupAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdatePopupAction) Init() {
 | 
			
		||||
	this.Nav("", "", "")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdatePopupAction) RunGet(params struct {
 | 
			
		||||
	AccountId int64
 | 
			
		||||
}) {
 | 
			
		||||
	// 账号信息
 | 
			
		||||
	accountResp, err := this.RPC().ACMEProviderAccountRPC().FindEnabledACMEProviderAccount(this.AdminContext(), &pb.FindEnabledACMEProviderAccountRequest{AcmeProviderAccountId: params.AccountId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var account = accountResp.AcmeProviderAccount
 | 
			
		||||
	if account == nil {
 | 
			
		||||
		this.NotFound("ACMEProviderAccount", params.AccountId)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var providerMap maps.Map
 | 
			
		||||
	if account.AcmeProvider != nil {
 | 
			
		||||
		providerMap = maps.Map{
 | 
			
		||||
			"name":           account.AcmeProvider.Name,
 | 
			
		||||
			"code":           account.AcmeProvider.Code,
 | 
			
		||||
			"description":    account.AcmeProvider.Description,
 | 
			
		||||
			"eabDescription": account.AcmeProvider.EabDescription,
 | 
			
		||||
			"requireEAB":     account.AcmeProvider.RequireEAB,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["account"] = maps.Map{
 | 
			
		||||
		"id":           account.Id,
 | 
			
		||||
		"name":         account.Name,
 | 
			
		||||
		"isOn":         account.IsOn,
 | 
			
		||||
		"providerCode": account.ProviderCode,
 | 
			
		||||
		"eabKid":       account.EabKid,
 | 
			
		||||
		"eabKey":       account.EabKey,
 | 
			
		||||
		"provider":     providerMap,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdatePopupAction) RunPost(params struct {
 | 
			
		||||
	AccountId    int64
 | 
			
		||||
	Name         string
 | 
			
		||||
	ProviderCode string
 | 
			
		||||
	EabKid       string
 | 
			
		||||
	EabKey       string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
}) {
 | 
			
		||||
	defer this.CreateLogInfo("修改ACME服务商账号 %d", params.AccountId)
 | 
			
		||||
 | 
			
		||||
	params.Must.
 | 
			
		||||
		Field("name", params.Name).
 | 
			
		||||
		Require("请输入账号名称").
 | 
			
		||||
		Field("providerCode", params.ProviderCode).
 | 
			
		||||
		Require("请选择服务商")
 | 
			
		||||
 | 
			
		||||
	providerResp, err := this.RPC().ACMEProviderRPC().FindACMEProviderWithCode(this.AdminContext(), &pb.FindACMEProviderWithCodeRequest{AcmeProviderCode: params.ProviderCode})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var provider = providerResp.AcmeProvider
 | 
			
		||||
	if provider == nil {
 | 
			
		||||
		this.Fail("请选择服务商")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if provider.RequireEAB {
 | 
			
		||||
		params.Must.
 | 
			
		||||
			Field("eabKid", params.EabKid).
 | 
			
		||||
			Require("请输入EAB Kid").
 | 
			
		||||
			Field("eabKey", params.EabKey).
 | 
			
		||||
			Require("请输入EAB HMAC Key")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err = this.RPC().ACMEProviderAccountRPC().UpdateACMEProviderAccount(this.AdminContext(), &pb.UpdateACMEProviderAccountRequest{
 | 
			
		||||
		AcmeProviderAccountId: params.AccountId,
 | 
			
		||||
		Name:                  params.Name,
 | 
			
		||||
		EabKid:                params.EabKid,
 | 
			
		||||
		EabKey:                params.EabKey,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -35,15 +35,31 @@ func (this *CreateAction) RunGet(params struct{}) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		userMaps = append(userMaps, maps.Map{
 | 
			
		||||
			"id":          user.Id,
 | 
			
		||||
			"description": description,
 | 
			
		||||
			"email":       user.Email,
 | 
			
		||||
			"id":           user.Id,
 | 
			
		||||
			"description":  description,
 | 
			
		||||
			"email":        user.Email,
 | 
			
		||||
			"providerCode": user.AcmeProviderCode,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["users"] = userMaps
 | 
			
		||||
 | 
			
		||||
	// 证书服务商
 | 
			
		||||
	providersResp, err := this.RPC().ACMEProviderRPC().FindAllACMEProviders(this.AdminContext(), &pb.FindAllACMEProvidersRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var providerMaps = []maps.Map{}
 | 
			
		||||
	for _, provider := range providersResp.AcmeProviders {
 | 
			
		||||
		providerMaps = append(providerMaps, maps.Map{
 | 
			
		||||
			"name": provider.Name,
 | 
			
		||||
			"code": provider.Code,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["providers"] = providerMaps
 | 
			
		||||
 | 
			
		||||
	// 域名解析服务商
 | 
			
		||||
	providersResp, err := this.RPC().DNSProviderRPC().FindAllEnabledDNSProviders(this.AdminContext(), &pb.FindAllEnabledDNSProvidersRequest{
 | 
			
		||||
	dnsProvidersResp, err := this.RPC().DNSProviderRPC().FindAllEnabledDNSProviders(this.AdminContext(), &pb.FindAllEnabledDNSProvidersRequest{
 | 
			
		||||
		AdminId: this.AdminId(),
 | 
			
		||||
		UserId:  0,
 | 
			
		||||
	})
 | 
			
		||||
@@ -51,15 +67,15 @@ func (this *CreateAction) RunGet(params struct{}) {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	providerMaps := []maps.Map{}
 | 
			
		||||
	for _, provider := range providersResp.DnsProviders {
 | 
			
		||||
		providerMaps = append(providerMaps, maps.Map{
 | 
			
		||||
	dnsProviderMaps := []maps.Map{}
 | 
			
		||||
	for _, provider := range dnsProvidersResp.DnsProviders {
 | 
			
		||||
		dnsProviderMaps = append(dnsProviderMaps, maps.Map{
 | 
			
		||||
			"id":       provider.Id,
 | 
			
		||||
			"name":     provider.Name,
 | 
			
		||||
			"typeName": provider.TypeName,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["providers"] = providerMaps
 | 
			
		||||
	this.Data["dnsProviders"] = dnsProviderMaps
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -136,6 +136,26 @@ func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
		if task.AcmeUser == nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 服务商
 | 
			
		||||
		var providerMap maps.Map
 | 
			
		||||
		if task.AcmeUser.AcmeProvider != nil {
 | 
			
		||||
			providerMap = maps.Map{
 | 
			
		||||
				"name": task.AcmeUser.AcmeProvider.Name,
 | 
			
		||||
				"code": task.AcmeUser.AcmeProvider.Code,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 账号
 | 
			
		||||
		var accountMap maps.Map
 | 
			
		||||
		if task.AcmeUser.AcmeProviderAccount != nil {
 | 
			
		||||
			accountMap = maps.Map{
 | 
			
		||||
				"id":   task.AcmeUser.AcmeProviderAccount.Id,
 | 
			
		||||
				"name": task.AcmeUser.AcmeProviderAccount.Name,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// DNS服务商
 | 
			
		||||
		dnsProviderMap := maps.Map{}
 | 
			
		||||
		if task.AuthType == "dns" && task.DnsProvider != nil {
 | 
			
		||||
			dnsProviderMap = maps.Map{
 | 
			
		||||
@@ -170,8 +190,10 @@ func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
			"id":       task.Id,
 | 
			
		||||
			"authType": task.AuthType,
 | 
			
		||||
			"acmeUser": maps.Map{
 | 
			
		||||
				"id":    task.AcmeUser.Id,
 | 
			
		||||
				"email": task.AcmeUser.Email,
 | 
			
		||||
				"id":       task.AcmeUser.Id,
 | 
			
		||||
				"email":    task.AcmeUser.Email,
 | 
			
		||||
				"provider": providerMap,
 | 
			
		||||
				"account":  accountMap,
 | 
			
		||||
			},
 | 
			
		||||
			"dnsProvider": dnsProviderMap,
 | 
			
		||||
			"dnsDomain":   task.DnsDomain,
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package users
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type AccountsWithCodeAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *AccountsWithCodeAction) RunPost(params struct {
 | 
			
		||||
	Code string
 | 
			
		||||
}) {
 | 
			
		||||
	accountsResp, err := this.RPC().ACMEProviderAccountRPC().FindAllACMEProviderAccountsWithProviderCode(this.AdminContext(), &pb.FindAllACMEProviderAccountsWithProviderCodeRequest{AcmeProviderCode: params.Code})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var accountMaps = []maps.Map{}
 | 
			
		||||
	for _, account := range accountsResp.AcmeProviderAccounts {
 | 
			
		||||
		accountMaps = append(accountMaps, maps.Map{
 | 
			
		||||
			"id":   account.Id,
 | 
			
		||||
			"name": account.Name,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["accounts"] = accountMaps
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -16,12 +16,30 @@ func (this *CreatePopupAction) Init() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreatePopupAction) RunGet(params struct{}) {
 | 
			
		||||
	// 服务商
 | 
			
		||||
	providersResp, err := this.RPC().ACMEProviderRPC().FindAllACMEProviders(this.AdminContext(), &pb.FindAllACMEProvidersRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var providerMaps = []maps.Map{}
 | 
			
		||||
	for _, provider := range providersResp.AcmeProviders {
 | 
			
		||||
		providerMaps = append(providerMaps, maps.Map{
 | 
			
		||||
			"code":       provider.Code,
 | 
			
		||||
			"name":       provider.Name,
 | 
			
		||||
			"requireEAB": provider.RequireEAB,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["providers"] = providerMaps
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreatePopupAction) RunPost(params struct {
 | 
			
		||||
	Email       string
 | 
			
		||||
	Description string
 | 
			
		||||
	Email        string
 | 
			
		||||
	ProviderCode string
 | 
			
		||||
	AccountId    int64
 | 
			
		||||
	Description  string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
@@ -29,11 +47,29 @@ func (this *CreatePopupAction) RunPost(params struct {
 | 
			
		||||
	params.Must.
 | 
			
		||||
		Field("email", params.Email).
 | 
			
		||||
		Require("请输入邮箱").
 | 
			
		||||
		Email("请输入正确的邮箱格式")
 | 
			
		||||
		Email("请输入正确的邮箱格式").
 | 
			
		||||
		Field("providerCode", params.ProviderCode).
 | 
			
		||||
		Require("请选择所属服务商")
 | 
			
		||||
 | 
			
		||||
	providerResp, err := this.RPC().ACMEProviderRPC().FindACMEProviderWithCode(this.AdminContext(), &pb.FindACMEProviderWithCodeRequest{
 | 
			
		||||
		AcmeProviderCode: params.ProviderCode,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if providerResp.AcmeProvider == nil {
 | 
			
		||||
		this.Fail("找不到要选择的证书")
 | 
			
		||||
	}
 | 
			
		||||
	if providerResp.AcmeProvider.RequireEAB && params.AccountId <= 0 {
 | 
			
		||||
		this.Fail("此服务商要求必须选择或创建服务商账号")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	createResp, err := this.RPC().ACMEUserRPC().CreateACMEUser(this.AdminContext(), &pb.CreateACMEUserRequest{
 | 
			
		||||
		Email:       params.Email,
 | 
			
		||||
		Description: params.Description,
 | 
			
		||||
		Email:                 params.Email,
 | 
			
		||||
		Description:           params.Description,
 | 
			
		||||
		AcmeProviderCode:      params.ProviderCode,
 | 
			
		||||
		AcmeProviderAccountId: params.AccountId,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
@@ -42,9 +78,10 @@ func (this *CreatePopupAction) RunPost(params struct {
 | 
			
		||||
 | 
			
		||||
	// 返回数据
 | 
			
		||||
	this.Data["acmeUser"] = maps.Map{
 | 
			
		||||
		"id":          createResp.AcmeUserId,
 | 
			
		||||
		"description": params.Description,
 | 
			
		||||
		"email":       params.Email,
 | 
			
		||||
		"id":           createResp.AcmeUserId,
 | 
			
		||||
		"description":  params.Description,
 | 
			
		||||
		"email":        params.Email,
 | 
			
		||||
		"providerCode": params.ProviderCode,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 日志
 | 
			
		||||
 
 | 
			
		||||
@@ -40,11 +40,31 @@ func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
	}
 | 
			
		||||
	userMaps := []maps.Map{}
 | 
			
		||||
	for _, user := range usersResp.AcmeUsers {
 | 
			
		||||
		// 服务商
 | 
			
		||||
		var providerMap maps.Map
 | 
			
		||||
		if user.AcmeProvider != nil {
 | 
			
		||||
			providerMap = maps.Map{
 | 
			
		||||
				"name": user.AcmeProvider.Name,
 | 
			
		||||
				"code": user.AcmeProvider.Code,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 账号
 | 
			
		||||
		var accountMap maps.Map
 | 
			
		||||
		if user.AcmeProviderAccount != nil {
 | 
			
		||||
			accountMap = maps.Map{
 | 
			
		||||
				"id":   user.AcmeProviderAccount.Id,
 | 
			
		||||
				"name": user.AcmeProviderAccount.Name,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		userMaps = append(userMaps, maps.Map{
 | 
			
		||||
			"id":          user.Id,
 | 
			
		||||
			"email":       user.Email,
 | 
			
		||||
			"description": user.Description,
 | 
			
		||||
			"createdTime": timeutil.FormatTime("Y-m-d H:i:s", user.CreatedAt),
 | 
			
		||||
			"provider":    providerMap,
 | 
			
		||||
			"account":     accountMap,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["users"] = userMaps
 | 
			
		||||
 
 | 
			
		||||
@@ -29,10 +29,30 @@ func (this *UpdatePopupAction) RunGet(params struct {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 服务商
 | 
			
		||||
	var providerMap maps.Map
 | 
			
		||||
	if user.AcmeProvider != nil {
 | 
			
		||||
		providerMap = maps.Map{
 | 
			
		||||
			"name": user.AcmeProvider.Name,
 | 
			
		||||
			"code": user.AcmeProvider.Code,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 账号
 | 
			
		||||
	var accountMap maps.Map
 | 
			
		||||
	if user.AcmeProviderAccount != nil {
 | 
			
		||||
		accountMap = maps.Map{
 | 
			
		||||
			"id":   user.AcmeProviderAccount.Id,
 | 
			
		||||
			"name": user.AcmeProviderAccount.Name,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["user"] = maps.Map{
 | 
			
		||||
		"id":          user.Id,
 | 
			
		||||
		"email":       user.Email,
 | 
			
		||||
		"description": user.Description,
 | 
			
		||||
		"provider":    providerMap,
 | 
			
		||||
		"account":     accountMap,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package certs
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/certs/acme"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/certs/acme/accounts"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/certs/acme/users"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
@@ -13,9 +14,7 @@ func init() {
 | 
			
		||||
		server.
 | 
			
		||||
			Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
 | 
			
		||||
			Helper(NewHelper()).
 | 
			
		||||
 | 
			
		||||
			Data("teaSubMenu", "cert").
 | 
			
		||||
 | 
			
		||||
			Prefix("/servers/certs").
 | 
			
		||||
			Data("leftMenuItem", "cert").
 | 
			
		||||
			Get("", new(IndexAction)).
 | 
			
		||||
@@ -31,7 +30,7 @@ func init() {
 | 
			
		||||
			Get("/selectPopup", new(SelectPopupAction)).
 | 
			
		||||
			Get("/datajs", new(DatajsAction)).
 | 
			
		||||
 | 
			
		||||
			// ACME
 | 
			
		||||
			// ACME任务
 | 
			
		||||
			Prefix("/servers/certs/acme").
 | 
			
		||||
			Data("leftMenuItem", "acme").
 | 
			
		||||
			Get("", new(acme.IndexAction)).
 | 
			
		||||
@@ -40,13 +39,23 @@ func init() {
 | 
			
		||||
			GetPost("/updateTaskPopup", new(acme.UpdateTaskPopupAction)).
 | 
			
		||||
			Post("/deleteTask", new(acme.DeleteTaskAction)).
 | 
			
		||||
 | 
			
		||||
			// ACME用户
 | 
			
		||||
			Prefix("/servers/certs/acme/users").
 | 
			
		||||
			Get("", new(users.IndexAction)).
 | 
			
		||||
			GetPost("/createPopup", new(users.CreatePopupAction)).
 | 
			
		||||
			GetPost("/updatePopup", new(users.UpdatePopupAction)).
 | 
			
		||||
			Post("/delete", new(users.DeleteAction)).
 | 
			
		||||
			GetPost("/selectPopup", new(users.SelectPopupAction)).
 | 
			
		||||
			Post("/accountsWithCode", new(users.AccountsWithCodeAction)).
 | 
			
		||||
 | 
			
		||||
			// ACME账号
 | 
			
		||||
			Prefix("/servers/certs/acme/accounts").
 | 
			
		||||
			Get("", new(accounts.IndexAction)).
 | 
			
		||||
			GetPost("/createPopup", new(accounts.CreatePopupAction)).
 | 
			
		||||
			GetPost("/updatePopup", new(accounts.UpdatePopupAction)).
 | 
			
		||||
			Post("/delete", new(accounts.DeleteAction)).
 | 
			
		||||
 | 
			
		||||
			//
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -75,6 +75,7 @@ Vue.component("http-webp-config-box", {
 | 
			
		||||
						<input type="checkbox" value="1" v-model="config.isOn"/>
 | 
			
		||||
						<label></label>
 | 
			
		||||
					</div>
 | 
			
		||||
					<p class="comment">选中后表示开启自动WebP压缩。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</tbody>
 | 
			
		||||
 
 | 
			
		||||
@@ -2,4 +2,5 @@
 | 
			
		||||
	<menu-item href="/servers/certs/acme" code="task">所有任务</menu-item>
 | 
			
		||||
	<menu-item href="/servers/certs/acme/create" code="create">新申请</menu-item>
 | 
			
		||||
	<menu-item href="/servers/certs/acme/users" code="user">ACME用户</menu-item>
 | 
			
		||||
    <menu-item href="/servers/certs/acme/accounts" code="account">服务商账号</menu-item>
 | 
			
		||||
</first-menu>
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,41 @@
 | 
			
		||||
{$layout "layout_popup"}
 | 
			
		||||
 | 
			
		||||
<h3>添加账号</h3>
 | 
			
		||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
    <csrf-token></csrf-token>
 | 
			
		||||
 | 
			
		||||
    <table class="ui table definition selectable">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>账号名称 *</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <input type="text" name="name" maxlength="50" ref="focus" tabindex="1"/>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td class="title">服务商 *</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <select class="ui dropdown auto-width" name="providerCode" v-model="providerCode" @change="changeProvider" tabindex="2">
 | 
			
		||||
                    <option value="">[选择服务商]</option>
 | 
			
		||||
                    <option v-for="provider in providers" :value="provider.code">{{provider.name}}</option>
 | 
			
		||||
                </select>
 | 
			
		||||
                <p class="comment" v-if="selectedProvider != null" v-html="selectedProvider.description"></p>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tbody v-show="selectedProvider != null && selectedProvider.requireEAB">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>EAB Kid *</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="eabKid" maxlength="100" tabindex="3"/>
 | 
			
		||||
                    <p class="comment" v-if="selectedProvider != null" v-html="selectedProvider.eabDescription"></p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>EAB HMAC Key *</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="eabKey" maxlength="300" tabindex="4"/>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
    <submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
@@ -0,0 +1,16 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.selectedProvider = null
 | 
			
		||||
	this.changeProvider = function () {
 | 
			
		||||
		if (this.providerCode.length == 0) {
 | 
			
		||||
			this.selectedProvider = null
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		let that = this
 | 
			
		||||
		this.selectedProvider = this.providers.$find(function (k, v) {
 | 
			
		||||
			return v.code == that.providerCode
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.changeProvider()
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										46
									
								
								web/views/@default/servers/certs/acme/accounts/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								web/views/@default/servers/certs/acme/accounts/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/left_menu_top"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box without-tabbar">
 | 
			
		||||
    {$template "../menu"}
 | 
			
		||||
 | 
			
		||||
    <second-menu>
 | 
			
		||||
        <menu-item @click.prevent="createAccount">[创建账号]</menu-item>
 | 
			
		||||
    </second-menu>
 | 
			
		||||
 | 
			
		||||
    <p class="comment" v-if="accounts.length == 0">暂时还没有服务商账号。</p>
 | 
			
		||||
 | 
			
		||||
    <table class="ui table selectable celled" v-if="accounts.length > 0">
 | 
			
		||||
        <thead>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <th>名称</th>
 | 
			
		||||
                <th>服务商</th>
 | 
			
		||||
                <th class="four wide">EAB Kid</th>
 | 
			
		||||
                <th class="four wide">EBA HMAC Key</th>
 | 
			
		||||
                <th class="two wide">操作</th>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </thead>
 | 
			
		||||
        <tr v-for="account in accounts">
 | 
			
		||||
            <td>
 | 
			
		||||
                <a href="" @click.prevent="updateAccount(account.id)">{{account.name}} <i class="icon clone outline small"></i></a>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="account.provider != null">{{account.provider.name}}</span>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="account.eabKid.length > 0">{{account.eabKid}}</span>
 | 
			
		||||
                <span v-else class="disabled">-</span>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="account.eabKey.length > 0">{{account.eabKey}}</span>
 | 
			
		||||
                <span v-else class="disabled">-</span>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <a href="" @click.prevent="updateAccount(account.id)">修改</a>  
 | 
			
		||||
                <a href="" @click.prevent="deleteAccount(account.id)">删除</a>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <div class="page" v-html="page"></div>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										33
									
								
								web/views/@default/servers/certs/acme/accounts/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								web/views/@default/servers/certs/acme/accounts/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.createAccount = function () {
 | 
			
		||||
		teaweb.popup(".createPopup", {
 | 
			
		||||
			height: "24em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
					teaweb.reload()
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.updateAccount = function (accountId) {
 | 
			
		||||
		teaweb.popup(".updatePopup?accountId=" + accountId, {
 | 
			
		||||
			height: "24em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
					teaweb.reload()
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.deleteAccount = function (accountId) {
 | 
			
		||||
		teaweb.confirm("确定要删除此账号吗?", function () {
 | 
			
		||||
			this.$post(".delete")
 | 
			
		||||
				.params({
 | 
			
		||||
					accountId: accountId
 | 
			
		||||
				})
 | 
			
		||||
				.refresh()
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
@@ -0,0 +1,41 @@
 | 
			
		||||
{$layout "layout_popup"}
 | 
			
		||||
 | 
			
		||||
<h3>修改账号</h3>
 | 
			
		||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
    <csrf-token></csrf-token>
 | 
			
		||||
 | 
			
		||||
    <input type="hidden" name="accountId" :value="account.id"/>
 | 
			
		||||
    <input type="hidden" name="providerCode" :value="account.providerCode"/>
 | 
			
		||||
    <table class="ui table definition selectable">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>账号名称 *</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <input type="text" name="name" maxlength="50" ref="focus" v-model="account.name" tabindex="1"/>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td class="title">服务商 *</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <span v-if="account.provider != null">{{account.provider.name}}</span>
 | 
			
		||||
                <span v-else class="disabled">服务商已失效</span>
 | 
			
		||||
                <p class="comment" v-if="account.provider != null" v-html="account.provider.description"></p>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tbody v-show="account.provider != null && account.provider.requireEAB">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>EAB Kid *</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="eabKid" maxlength="100" v-model="account.eabKid" tabindex="3"/>
 | 
			
		||||
                    <p class="comment" v-if="account.provider != null" v-html="account.provider.eabDescription"></p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>EAB HMAC Key *</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="eabKey" maxlength="300" v-model="account.eabKey" tabindex="4"/>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
    <submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
@@ -0,0 +1,3 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
@@ -64,15 +64,24 @@
 | 
			
		||||
		<!-- 选择用户 -->
 | 
			
		||||
		<div v-show="step == 'user'">
 | 
			
		||||
			<table class="ui table definition selectable">
 | 
			
		||||
				<tr>
 | 
			
		||||
					<td class="title">选择用户</td>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td class="title">选择服务商 *</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <select class="ui dropdown auto-width" v-model="providerCode" @change="changeProvider">
 | 
			
		||||
                            <option value="">[选择服务商]</option>
 | 
			
		||||
                            <option v-for="provider in providers" :value="provider.code">{{provider.name}}</option>
 | 
			
		||||
                        </select>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
				<tr v-if="providerCode.length > 0">
 | 
			
		||||
					<td class="title">选择用户 *</td>
 | 
			
		||||
					<td>
 | 
			
		||||
						<div v-if="users.length > 0">
 | 
			
		||||
							<div class="ui fields inline">
 | 
			
		||||
								<div class="ui field">
 | 
			
		||||
									<select class="ui dropdown" v-model="userId">
 | 
			
		||||
										<option value="0">[请选择]</option>
 | 
			
		||||
										<option v-for="user in users" :value="user.id">{{user.email}}{{user.description}}</option>
 | 
			
		||||
										<option v-for="user in users" :value="user.id" v-if="user.providerCode == providerCode">{{user.email}}{{user.description}}</option>
 | 
			
		||||
									</select>
 | 
			
		||||
								</div>
 | 
			
		||||
								<div class="ui field">
 | 
			
		||||
@@ -98,10 +107,10 @@
 | 
			
		||||
				<tr v-show="authType == 'dns'">
 | 
			
		||||
					<td class="title">选择DNS服务商 *</td>
 | 
			
		||||
					<td>
 | 
			
		||||
						<div v-if="providers.length > 0">
 | 
			
		||||
						<div v-if="dnsProviders.length > 0">
 | 
			
		||||
							<select class="ui dropdown auto-width" v-model="dnsProviderId">
 | 
			
		||||
								<option value="0">[请选择]</option>
 | 
			
		||||
								<option v-for="provider in providers" :value="provider.id">{{provider.name}}({{provider.typeName}})</option>
 | 
			
		||||
								<option v-for="provider in dnsProviders" :value="provider.id">{{provider.name}}({{provider.typeName}})</option>
 | 
			
		||||
							</select>
 | 
			
		||||
						</div>
 | 
			
		||||
						<p class="comment">用于自动创建域名解析记录。</p>
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,8 @@ Tea.context(function () {
 | 
			
		||||
	this.createUser = function () {
 | 
			
		||||
		let that = this
 | 
			
		||||
		teaweb.popup("/servers/certs/acme/users/createPopup", {
 | 
			
		||||
			height: "27em",
 | 
			
		||||
			width: "44em",
 | 
			
		||||
			callback: function (resp) {
 | 
			
		||||
				teaweb.successToast("创建成功")
 | 
			
		||||
 | 
			
		||||
@@ -40,13 +42,23 @@ Tea.context(function () {
 | 
			
		||||
				that.users.unshift({
 | 
			
		||||
					id: acmeUser.id,
 | 
			
		||||
					description: description,
 | 
			
		||||
					email: acmeUser.email
 | 
			
		||||
					email: acmeUser.email,
 | 
			
		||||
					providerCode: acmeUser.providerCode
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.providerCode = ""
 | 
			
		||||
	this.changeProvider = function () {
 | 
			
		||||
		this.userId = 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.doUser = function () {
 | 
			
		||||
		if (this.providerCode.length == 0) {
 | 
			
		||||
			teaweb.warn("请选择一个证书服务商")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if (this.userId == 0) {
 | 
			
		||||
			teaweb.warn("请选择一个申请证书的用户")
 | 
			
		||||
			return
 | 
			
		||||
 
 | 
			
		||||
@@ -42,10 +42,12 @@
 | 
			
		||||
		</thead>
 | 
			
		||||
		<tr v-for="(task, index) in tasks" :class="{warning: runningIndex == index}">
 | 
			
		||||
			<td>{{task.acmeUser.email}}
 | 
			
		||||
				<div style="margin-top: 1em">
 | 
			
		||||
					<tiny-basic-label class="olive" v-if="task.authType == 'dns'">DNS</tiny-basic-label>
 | 
			
		||||
					<tiny-basic-label class="olive" v-if="task.authType == 'http'">HTTP</tiny-basic-label>
 | 
			
		||||
				</div>
 | 
			
		||||
                <div>
 | 
			
		||||
                    <grey-label class="olive" v-if="task.authType == 'dns'">DNS</grey-label>
 | 
			
		||||
                    <grey-label class="olive" v-if="task.authType == 'http'">HTTP</grey-label>
 | 
			
		||||
                    <grey-label v-if="task.acmeUser.provider != null">{{task.acmeUser.provider.name}}</grey-label>
 | 
			
		||||
                    <grey-label v-if="task.acmeUser.account != null">{{task.acmeUser.account.name}}</grey-label>
 | 
			
		||||
                </div>
 | 
			
		||||
			</td>
 | 
			
		||||
			<td nowrap="">
 | 
			
		||||
				<div v-for="domain in task.domains">
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,31 @@
 | 
			
		||||
				<p class="comment">用于自动注册用户的邮箱。</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>所属服务商 *</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <select class="ui dropdown auto-width" name="providerCode" v-model="providerCode" @change="changeProvider">
 | 
			
		||||
                    <option value="">[选择服务商]</option>
 | 
			
		||||
                    <option v-for="provider in providers" :value="provider.code">{{provider.name}}</option>
 | 
			
		||||
                </select>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr v-if="selectedProvider != null">
 | 
			
		||||
            <td>所属服务商账号 <span v-if="selectedProvider.requireEAB">*</span><em v-else>(可选)</em></td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <div class="ui fields inline">
 | 
			
		||||
                    <div class="ui field" v-if="accounts.length > 0">
 | 
			
		||||
                        <select class="ui dropdown auto-width" name="accountId" v-model="accountId">
 | 
			
		||||
                            <option value="0">[选择账号]</option>
 | 
			
		||||
                            <option v-for="account in accounts" :value="account.id">{{account.name}}</option>
 | 
			
		||||
                        </select>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="ui field">
 | 
			
		||||
                        <a href="" @click.prevent="addAccount">[添加]</a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>备注</td>
 | 
			
		||||
			<td>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										54
									
								
								web/views/@default/servers/certs/acme/users/createPopup.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								web/views/@default/servers/certs/acme/users/createPopup.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.providerCode = ""
 | 
			
		||||
	this.selectedProvider = null
 | 
			
		||||
	this.accounts = []
 | 
			
		||||
	this.accountId = 0
 | 
			
		||||
 | 
			
		||||
	this.changeProvider = function () {
 | 
			
		||||
		this.accountId = 0
 | 
			
		||||
 | 
			
		||||
		if (this.providerCode.length == 0) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		let that = this
 | 
			
		||||
		let provider = this.providers.$find(function (k, v) {
 | 
			
		||||
			return v.code == that.providerCode
 | 
			
		||||
		})
 | 
			
		||||
		if (provider == null) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.selectedProvider = provider
 | 
			
		||||
 | 
			
		||||
		this.$post(".accountsWithCode")
 | 
			
		||||
			.params({
 | 
			
		||||
				code: provider.code
 | 
			
		||||
			})
 | 
			
		||||
			.success(function (resp) {
 | 
			
		||||
				this.accounts = resp.data.accounts
 | 
			
		||||
			})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.addAccount = function () {
 | 
			
		||||
		let that = this
 | 
			
		||||
		teaweb.popup("/servers/certs/acme/accounts/createPopup?providerCode=" + this.providerCode, {
 | 
			
		||||
			height: "24em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.successToast("创建成功,已自动选中", 1500, function () {
 | 
			
		||||
					that.$post(".accountsWithCode")
 | 
			
		||||
						.params({
 | 
			
		||||
							code: that.providerCode
 | 
			
		||||
						})
 | 
			
		||||
						.success(function (resp) {
 | 
			
		||||
							that.accounts = resp.data.accounts
 | 
			
		||||
 | 
			
		||||
							if (that.accounts.length > 0) {
 | 
			
		||||
								that.accountId = that.accounts[0].id
 | 
			
		||||
							}
 | 
			
		||||
						})
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
@@ -14,13 +14,19 @@
 | 
			
		||||
	<table class="ui table selectable" v-if="users.length > 0">
 | 
			
		||||
		<thead>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<th>Email</th>
 | 
			
		||||
				<th>用户Email</th>
 | 
			
		||||
				<th>备注</th>
 | 
			
		||||
				<th class="two op">操作</th>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</thead>
 | 
			
		||||
		<tr v-for="user in users">
 | 
			
		||||
			<td>{{user.email}}</td>
 | 
			
		||||
			<td>
 | 
			
		||||
                <a href="" @click.prevent="updateUser(user.id)">{{user.email}} <i class="icon clone outline small"></i></a>
 | 
			
		||||
                <div>
 | 
			
		||||
                    <grey-label v-if="user.provider != null">{{user.provider.name}}</grey-label>
 | 
			
		||||
                    <grey-label v-if="user.account != null">{{user.account.name}}</grey-label>
 | 
			
		||||
                </div>
 | 
			
		||||
            </td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<span v-if="user.description.length > 0">{{user.description}}</span>
 | 
			
		||||
				<span v-else class="disabled">-</span>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.createUser = function () {
 | 
			
		||||
		teaweb.popup(Tea.url(".createPopup"), {
 | 
			
		||||
			height: "27em",
 | 
			
		||||
			width: "44em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("创建成功", function () {
 | 
			
		||||
					teaweb.reload()
 | 
			
		||||
@@ -11,6 +13,8 @@ Tea.context(function () {
 | 
			
		||||
 | 
			
		||||
	this.updateUser = function (userId) {
 | 
			
		||||
		teaweb.popup("/servers/certs/acme/users/updatePopup?userId=" + userId, {
 | 
			
		||||
			height: "27em",
 | 
			
		||||
			width: "44em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
					teaweb.reload()
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,14 @@
 | 
			
		||||
				<p class="comment">用于自动注册用户的邮箱,不允许修改。</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
        <tr v-if="user.provider != null">
 | 
			
		||||
            <td>所属服务商</td>
 | 
			
		||||
            <td>{{user.provider.name}}</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr v-if="user.account != null">
 | 
			
		||||
            <td>所属服务商账号</td>
 | 
			
		||||
            <td>{{user.account.name}}</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>备注</td>
 | 
			
		||||
			<td>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user