1
0
Эх сурвалжийг харах

feat: display info of multiple certificates in server tab.

Jacky 9 сар өмнө
parent
commit
e1a5521f4a

+ 4 - 23
api/sites/domain.go

@@ -66,7 +66,6 @@ func GetDomains(c *gin.Context) {
 
 func GetDomain(c *gin.Context) {
 	rewriteName, ok := c.Get("rewriteConfigFileName")
-
 	name := c.Param("name")
 
 	// for modify filename
@@ -84,14 +83,12 @@ func GetDomain(c *gin.Context) {
 	}
 
 	enabled := true
-
 	if _, err := os.Stat(nginx.GetConfPath("sites-enabled", name)); os.IsNotExist(err) {
 		enabled = false
 	}
 
 	g := query.ChatGPTLog
 	chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate()
-
 	if err != nil {
 		api.ErrHandler(c, err)
 		return
@@ -103,14 +100,12 @@ func GetDomain(c *gin.Context) {
 
 	s := query.Site
 	site, err := s.Where(s.Path.Eq(path)).FirstOrInit()
-
 	if err != nil {
 		api.ErrHandler(c, err)
 		return
 	}
 
 	certModel, err := model.FirstCert(name)
-
 	if err != nil {
 		logger.Warn(err)
 	}
@@ -136,28 +131,21 @@ func GetDomain(c *gin.Context) {
 	}
 
 	nginxConfig, err := nginx.ParseNgxConfig(path)
-
 	if err != nil {
 		api.ErrHandler(c, err)
 		return
 	}
 
-	certInfoMap := make(map[int]*cert.Info)
-
+	certInfoMap := make(map[int][]*cert.Info)
 	for serverIdx, server := range nginxConfig.Servers {
 		for _, directive := range server.Directives {
 			if directive.Directive == "ssl_certificate" {
-
 				pubKey, err := cert.GetCertInfo(directive.Params)
-
 				if err != nil {
 					logger.Error("Failed to get certificate information", err)
-					break
+					continue
 				}
-
-				certInfoMap[serverIdx] = pubKey
-
-				break
+				certInfoMap[serverIdx] = append(certInfoMap[serverIdx], pubKey)
 			}
 		}
 	}
@@ -291,9 +279,8 @@ func EnableDomain(c *gin.Context) {
 		}
 	}
 
-	// Test nginx config, if not pass then disable the site.
+	// Test nginx config, if not pass, then disable the site.
 	output := nginx.TestConf()
-
 	if nginx.GetLogLevel(output) > nginx.Warn {
 		_ = os.Remove(enabledConfigFilePath)
 		c.JSON(http.StatusInternalServerError, gin.H{
@@ -318,16 +305,13 @@ func EnableDomain(c *gin.Context) {
 
 func DisableDomain(c *gin.Context) {
 	enabledConfigFilePath := nginx.GetConfPath("sites-enabled", c.Param("name"))
-
 	_, err := os.Stat(enabledConfigFilePath)
-
 	if err != nil {
 		api.ErrHandler(c, err)
 		return
 	}
 
 	err = os.Remove(enabledConfigFilePath)
-
 	if err != nil {
 		api.ErrHandler(c, err)
 		return
@@ -342,7 +326,6 @@ func DisableDomain(c *gin.Context) {
 	}
 
 	output := nginx.Reload()
-
 	if nginx.GetLogLevel(output) > nginx.Warn {
 		c.JSON(http.StatusInternalServerError, gin.H{
 			"message": output,
@@ -360,7 +343,6 @@ func DeleteDomain(c *gin.Context) {
 	name := c.Param("name")
 	availablePath := nginx.GetConfPath("sites-available", name)
 	enabledPath := nginx.GetConfPath("sites-enabled", name)
-
 	if _, err = os.Stat(availablePath); os.IsNotExist(err) {
 		c.JSON(http.StatusNotFound, gin.H{
 			"message": "site not found",
@@ -379,7 +361,6 @@ func DeleteDomain(c *gin.Context) {
 	_ = certModel.Remove()
 
 	err = os.Remove(availablePath)
-
 	if err != nil {
 		api.ErrHandler(c, err)
 		return

+ 1 - 1
api/sites/sites.go

@@ -16,6 +16,6 @@ type Site struct {
 	AutoCert        bool                           `json:"auto_cert"`
 	ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"`
 	Tokenized       *nginx.NgxConfig               `json:"tokenized,omitempty"`
-	CertInfo        map[int]*cert.Info             `json:"cert_info,omitempty"`
+	CertInfo        map[int][]*cert.Info           `json:"cert_info,omitempty"`
 	Filepath        string                         `json:"filepath"`
 }

+ 1 - 3
app/src/api/domain.ts

@@ -15,9 +15,7 @@ export interface Site {
   auto_cert: boolean
   chatgpt_messages: ChatComplicationMessage[]
   tokenized?: NgxConfig
-  cert_info?: {
-    [key: number]: CertificateInfo
-  }
+  cert_info?: Record<number, CertificateInfo[]>
 }
 
 export interface AutoCertRequest {

+ 4 - 1
app/src/views/certificate/CertificateEditor.vue

@@ -126,7 +126,10 @@ const isManaged = computed(() => {
           layout="vertical"
         >
           <AFormItem :label="$gettext('Certificate Status')">
-            <CertInfo :cert="data.certificate_info" />
+            <CertInfo
+              :cert="data.certificate_info"
+              class="max-w-96"
+            />
           </AFormItem>
         </AForm>
 

+ 3 - 6
app/src/views/domain/DomainEdit.vue

@@ -29,7 +29,7 @@ const ngx_config: NgxConfig = reactive({
   servers: [],
 })
 
-const cert_info_map: Record<string, CertificateInfo> = reactive({})
+const certInfoMap: Ref<Record<number, CertificateInfo[]>> = ref({})
 
 const auto_cert = ref(false)
 const enabled = ref(false)
@@ -62,9 +62,6 @@ function handle_response(r: Site) {
   if (r.advanced)
     advance_mode.value = true
 
-  Object.keys(cert_info_map).forEach((v: string) => {
-    delete cert_info_map[v]
-  })
   parse_error_status.value = false
   parse_error_message.value = ''
   filename.value = r.name
@@ -74,8 +71,8 @@ function handle_response(r: Site) {
   auto_cert.value = r.auto_cert
   history_chatgpt_record.value = r.chatgpt_messages
   data.value = r
+  certInfoMap.value = r.cert_info || {}
   Object.assign(ngx_config, r.tokenized)
-  Object.assign(cert_info_map, r.cert_info)
 }
 
 function init() {
@@ -230,7 +227,7 @@ provide('data', data)
           >
             <NgxConfigEditor
               v-model:auto-cert="auto_cert"
-              :cert-info="cert_info_map"
+              :cert-info="certInfoMap"
               :enabled="enabled"
               @callback="save"
             />

+ 16 - 6
app/src/views/domain/cert/Cert.vue

@@ -8,7 +8,7 @@ const props = defineProps<{
   configName: string
   enabled: boolean
   currentServerIndex: number
-  certInfo?: CertificateInfo
+  certInfo?: CertificateInfo[]
 }>()
 
 const emit = defineEmits(['update:enabled'])
@@ -25,13 +25,23 @@ const enabled = computed({
 
 <template>
   <div>
-    <h2>
+    <h3>
       {{ $gettext('Certificate Status') }}
-    </h2>
-    <CertInfo
-      :cert="certInfo"
+    </h3>
+
+    <ARow
+      :gutter="[16, 16]"
       class="mb-4"
-    />
+    >
+      <ACol
+        v-for="(c, index) in certInfo"
+        :key="index"
+        :xs="24"
+        :sm="12"
+      >
+        <CertInfo :cert="c" />
+      </ACol>
+    </ARow>
 
     <ChangeCert />
 

+ 23 - 19
app/src/views/domain/cert/CertInfo.vue

@@ -1,42 +1,46 @@
 <script setup lang="ts">
-import { CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons-vue'
 import dayjs from 'dayjs'
 import type { CertificateInfo } from '@/api/cert'
 
-defineProps<{
+const props = defineProps<{
   cert?: CertificateInfo
 }>()
 
+const isValid = computed(() => dayjs().isAfter(props.cert?.not_before) && dayjs().isBefore(props.cert?.not_after))
 </script>
 
 <template>
-  <div
+  <ACard
     v-if="cert"
-    class="cert-info"
+    size="small"
   >
+    <template #title>
+      {{ cert.subject_name }}
+      <ATag
+        v-if="isValid"
+        color="success"
+        class="ml-2"
+      >
+        {{ $gettext('Valid') }}
+      </ATag>
+      <ATag
+        v-else
+        color="error"
+        class="ml-2"
+      >
+        {{ $gettext('Expired') }}
+      </ATag>
+    </template>
     <p>
       {{ $gettext('Intermediate Certification Authorities: %{issuer}', { issuer: cert.issuer_name }) }}
     </p>
-    <p>
-      {{ $gettext('Subject Name: %{subject}', { subject: cert.subject_name }) }}
-    </p>
     <p>
       {{ $gettext('Expired At: %{date}', { date: dayjs(cert.not_after).format('YYYY-MM-DD HH:mm:ss').toString() }) }}
     </p>
-    <p>
+    <p class="mb-0">
       {{ $gettext('Not Valid Before: %{date}', { date: dayjs(cert.not_before).format('YYYY-MM-DD HH:mm:ss').toString() }) }}
     </p>
-    <div class="status">
-      <template v-if="dayjs().isBefore(cert.not_before) || dayjs().isAfter(cert.not_after)">
-        <CloseCircleOutlined class="text-red-600" />
-        <span class="ml-2">{{ $gettext('Certificate has expired') }}</span>
-      </template>
-      <template v-else>
-        <CheckCircleOutlined class="text-green-500" />
-        <span class="ml-2">{{ $gettext('Certificate is valid') }}</span>
-      </template>
-    </div>
-  </div>
+  </ACard>
 </template>
 
 <style lang="less" scoped>

+ 1 - 1
app/src/views/domain/ngx_conf/NgxConfigEditor.vue

@@ -12,7 +12,7 @@ import type { CheckedType } from '@/types'
 const props = withDefaults(defineProps<{
   autoCert?: boolean
   enabled: boolean
-  certInfo?: Record<number, CertificateInfo>
+  certInfo?: Record<number, CertificateInfo[]>
   context?: 'http' | 'stream'
 }>(), {
   autoCert: false,

+ 1 - 1
app/src/views/domain/ngx_conf/NgxServer.vue

@@ -12,7 +12,7 @@ import type { CertificateInfo } from '@/api/cert'
 withDefaults(defineProps<{
   enabled: boolean
   certInfo?: {
-    [key: number]: CertificateInfo
+    [key: number]: CertificateInfo[]
   }
   context: 'http' | 'stream'
 }>(), {