2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 01:57:19 +08:00

feat: 不再支持手动签发证书

This commit is contained in:
2026-01-30 17:26:38 +08:00
parent 624bac6ead
commit 7ef6a5df0e
6 changed files with 4 additions and 173 deletions

View File

@@ -41,11 +41,9 @@ type CertRepo interface {
Update(ctx context.Context, req *request.CertUpdate) error
Delete(ctx context.Context, id uint) error
ObtainAuto(id uint) (*acme.Certificate, error)
ObtainManual(id uint) (*acme.Certificate, error)
ObtainPanel(account *CertAccount, ips []string) ([]byte, []byte, error)
ObtainSelfSigned(id uint) error
Renew(id uint) (*acme.Certificate, error)
RefreshRenewalInfo(id uint) (mholtacme.RenewalInfo, error)
ManualDNS(id uint) ([]acme.DNSRecord, error)
Deploy(ID, WebsiteID uint) error
}

View File

@@ -31,7 +31,6 @@ type certRepo struct {
db *gorm.DB
log *slog.Logger
settingRepo biz.SettingRepo
client *acme.Client
}
func NewCertRepo(t *gotext.Locale, db *gorm.DB, log *slog.Logger, settingRepo biz.SettingRepo) biz.CertRepo {
@@ -245,40 +244,6 @@ func (r *certRepo) ObtainAuto(id uint) (*acme.Certificate, error) {
return &ssl, nil
}
func (r *certRepo) ObtainManual(id uint) (*acme.Certificate, error) {
cert, err := r.Get(id)
if err != nil {
return nil, err
}
if r.client == nil {
return nil, errors.New(r.t.Get("please retry the manual obtain operation"))
}
ssl, err := r.client.ObtainCertificateManual()
if err != nil {
return nil, err
}
cert.RenewalInfo = *ssl.RenewalInfo
cert.CertURL = ssl.URL
cert.Cert = string(ssl.ChainPEM)
cert.Key = string(ssl.PrivateKey)
if err = r.db.Save(cert).Error; err != nil {
return nil, err
}
if cert.Website != nil {
return &ssl, r.Deploy(cert.ID, cert.WebsiteID)
}
if err = r.runScript(cert); err != nil {
return nil, err
}
return &ssl, nil
}
func (r *certRepo) ObtainPanel(account *biz.CertAccount, ips []string) ([]byte, []byte, error) {
client, err := acme.NewPrivateKeyAccount(account.Email, account.PrivateKey, acme.CALetsEncrypt, nil, r.log)
if err != nil {
@@ -419,34 +384,6 @@ func (r *certRepo) RefreshRenewalInfo(id uint) (mholtacme.RenewalInfo, error) {
return renewInfo, nil
}
func (r *certRepo) ManualDNS(id uint) ([]acme.DNSRecord, error) {
cert, err := r.Get(id)
if err != nil {
return nil, err
}
client, err := r.getClient(cert)
if err != nil {
return nil, err
}
client.UseManualDns()
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
records, err := client.GetDNSRecords(ctx, cert.Domains, acme.KeyType(cert.Type))
if err != nil {
return nil, err
}
// 15 分钟后清理客户端
r.client = client
time.AfterFunc(15*time.Minute, func() {
r.client = nil
})
return records, nil
}
func (r *certRepo) Deploy(ID, WebsiteID uint) error {
cert, err := r.Get(ID)
if err != nil {
@@ -501,12 +438,9 @@ func (r *certRepo) runScript(cert *biz.Cert) error {
if _, err = f.WriteString(cert.Script); err != nil {
return err
}
if err = f.Chmod(0755); err != nil {
return err
}
if err = f.Close(); err != nil {
return err
}
_ = f.Chmod(0755)
_ = f.Close()
defer func(name string) { _ = os.Remove(name) }(f.Name())
_, err = shell.Execf("bash " + f.Name())

View File

@@ -288,10 +288,8 @@ func (route *Http) Register(r *chi.Mux) {
r.Get("/{id}", route.cert.Get)
r.Delete("/{id}", route.cert.Delete)
r.Post("/{id}/obtain_auto", route.cert.ObtainAuto)
r.Post("/{id}/obtain_manual", route.cert.ObtainManual)
r.Post("/{id}/obtain_self_signed", route.cert.ObtainSelfSigned)
r.Post("/{id}/renew", route.cert.Renew)
r.Post("/{id}/manual_dns", route.cert.ManualDNS)
r.Post("/{id}/deploy", route.cert.Deploy)
})
r.Route("/dns", func(r chi.Router) {

View File

@@ -234,21 +234,6 @@ func (s *CertService) ObtainAuto(w http.ResponseWriter, r *http.Request) {
Success(w, nil)
}
func (s *CertService) ObtainManual(w http.ResponseWriter, r *http.Request) {
req, err := Bind[request.ID](r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, "%v", err)
return
}
if _, err = s.certRepo.ObtainManual(req.ID); err != nil {
Error(w, http.StatusInternalServerError, "%v", err)
return
}
Success(w, nil)
}
func (s *CertService) ObtainSelfSigned(w http.ResponseWriter, r *http.Request) {
req, err := Bind[request.ID](r)
if err != nil {
@@ -280,22 +265,6 @@ func (s *CertService) Renew(w http.ResponseWriter, r *http.Request) {
Success(w, nil)
}
func (s *CertService) ManualDNS(w http.ResponseWriter, r *http.Request) {
req, err := Bind[request.ID](r)
if err != nil {
Error(w, http.StatusUnprocessableEntity, "%v", err)
return
}
dns, err := s.certRepo.ManualDNS(req.ID)
if err != nil {
Error(w, http.StatusInternalServerError, "%v", err)
return
}
Success(w, dns)
}
func (s *CertService) Deploy(w http.ResponseWriter, r *http.Request) {
req, err := Bind[request.CertDeploy](r)
if err != nil {

View File

@@ -42,14 +42,10 @@ export default {
certDelete: (id: number): any => http.Delete(`/cert/cert/${id}`),
// 证书自动签发
obtainAuto: (id: number): any => http.Post(`/cert/cert/${id}/obtain_auto`, { id }),
// 证书手动签发
obtainManual: (id: number): any => http.Post(`/cert/cert/${id}/obtain_manual`, { id }),
// 证书自签名签发
obtainSelfSigned: (id: number): any => http.Post(`/cert/cert/${id}/obtain_self_signed`, { id }),
// 续签
renew: (id: number): any => http.Post(`/cert/cert/${id}/renew`, { id }),
// 获取 DNS 记录
manualDNS: (id: number): any => http.Post(`/cert/cert/${id}/manual_dns`, { id }),
// 部署
deploy: (id: number, website_id: number): any =>
http.Post(`/cert/cert/${id}/deploy`, { id, website_id })

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import cert from '@/api/panel/cert'
import type { MessageReactive } from 'naive-ui'
import { NButton, NTable } from 'naive-ui'
import { NButton } from 'naive-ui'
import { useGettext } from 'vue3-gettext'
const { $gettext } = useGettext()
@@ -16,7 +16,6 @@ const model = ref({
const options = [
{ label: $gettext('Automatic'), value: 'auto' },
{ label: $gettext('Manual'), value: 'manual' },
{ label: $gettext('Self-signed'), value: 'self-signed' }
]
@@ -35,69 +34,6 @@ const handleSubmit = () => {
.onComplete(() => {
messageReactive?.destroy()
})
} else if (model.value.type == 'manual') {
useRequest(cert.manualDNS(id.value))
.onSuccess(({ data }: { data: any }) => {
window.$message.info(
$gettext(
'Please set up DNS resolution for the domain first, then continue with the issuance'
)
)
const d = window.$dialog.info({
style: 'width: 60vw',
title: $gettext('DNS Records to Set'),
content: () => {
return h(
NTable,
{},
{
default: () => [
h('thead', [
h('tr', [
h('th', $gettext('Domain')),
h('th', $gettext('Type')),
h('th', $gettext('Host Record')),
h('th', $gettext('Record Value'))
])
]),
h(
'tbody',
data.map((item: any) =>
h('tr', [
h('td', item?.domain),
h('td', 'TXT'),
h('td', item?.name),
h('td', item?.value)
])
)
)
]
}
)
},
positiveText: $gettext('Issue'),
onPositiveClick: async () => {
d.loading = true
messageReactive = window.$message.loading($gettext('Please wait...'), {
duration: 0
})
useRequest(cert.obtainManual(id.value))
.onSuccess(() => {
window.$bus.emit('cert:refresh-cert')
window.$bus.emit('cert:refresh-async')
show.value = false
window.$message.success($gettext('Issuance successful'))
})
.onComplete(() => {
d.loading = false
messageReactive?.destroy()
})
}
})
})
.onComplete(() => {
messageReactive?.destroy()
})
} else {
useRequest(cert.obtainSelfSigned(id.value))
.onSuccess(() => {