| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 | package certificateimport (	"github.com/0xJacky/Nginx-UI/internal/cert"	"github.com/0xJacky/Nginx-UI/internal/logger"	"github.com/0xJacky/Nginx-UI/model"	"github.com/gin-gonic/gin"	"github.com/go-acme/lego/v4/certcrypto"	"github.com/gorilla/websocket"	"net/http")const (	Success = "success"	Info    = "info"	Error   = "error")type IssueCertResponse struct {	Status            string             `json:"status"`	Message           string             `json:"message"`	SSLCertificate    string             `json:"ssl_certificate,omitempty"`	SSLCertificateKey string             `json:"ssl_certificate_key,omitempty"`	KeyType           certcrypto.KeyType `json:"key_type"`}func handleIssueCertLogChan(conn *websocket.Conn, log *cert.Logger, logChan chan string) {	defer func() {		if err := recover(); err != nil {			logger.Error(err)		}	}()	for logString := range logChan {		log.Info(logString)		err := conn.WriteJSON(IssueCertResponse{			Status:  Info,			Message: logString,		})		if err != nil {			logger.Error(err)			return		}	}}func IssueCert(c *gin.Context) {	var upGrader = websocket.Upgrader{		CheckOrigin: func(r *http.Request) bool {			return true		},	}	// upgrade http to websocket	ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)	if err != nil {		logger.Error(err)		return	}	defer func(ws *websocket.Conn) {		_ = ws.Close()	}(ws)	// read	payload := &cert.ConfigPayload{}	err = ws.ReadJSON(payload)	if err != nil {		logger.Error(err)		return	}	certModel, err := model.FirstOrCreateCert(c.Param("name"), payload.GetKeyType())	if err != nil {		logger.Error(err)		return	}	certInfo, _ := cert.GetCertInfo(certModel.SSLCertificatePath)	if certInfo != nil {		payload.Resource = certModel.Resource		payload.NotBefore = certInfo.NotBefore	}	logChan := make(chan string, 1)	errChan := make(chan error, 1)	log := &cert.Logger{}	log.SetCertModel(&certModel)	payload.CertID = certModel.ID	go cert.IssueCert(payload, logChan, errChan)	go handleIssueCertLogChan(ws, log, logChan)	// block, until errChan closes	for err = range errChan {		log.Error(err)		// Save logs to db		log.Exit()		err = ws.WriteJSON(IssueCertResponse{			Status:  Error,			Message: err.Error(),		})		if err != nil {			logger.Error(err)			return		}		return	}	err = certModel.Updates(&model.Cert{		Domains:                 payload.ServerName,		SSLCertificatePath:      payload.GetCertificatePath(),		SSLCertificateKeyPath:   payload.GetCertificateKeyPath(),		AutoCert:                model.AutoCertEnabled,		KeyType:                 payload.KeyType,		ChallengeMethod:         payload.ChallengeMethod,		DnsCredentialID:         payload.DNSCredentialID,		Resource:                payload.Resource,		MustStaple:              payload.MustStaple,		LegoDisableCNAMESupport: payload.LegoDisableCNAMESupport,	})	if err != nil {		logger.Error(err)		_ = ws.WriteJSON(IssueCertResponse{			Status:  Error,			Message: err.Error(),		})		return	}	// Save logs to db	log.Exit()	err = ws.WriteJSON(IssueCertResponse{		Status:            Success,		Message:           "Issued certificate successfully",		SSLCertificate:    payload.GetCertificatePath(),		SSLCertificateKey: payload.GetCertificateKeyPath(),		KeyType:           payload.GetKeyType(),	})	if err != nil {		logger.Error(err)		return	}}
 |