Kaynağa Gözat

refactor(change_cert): support select multiple certificates #437

Jacky 1 yıl önce
ebeveyn
işleme
ada02323d8

+ 0 - 1
app/src/components/CodeEditor/CodeEditor.vue

@@ -4,7 +4,6 @@ import 'ace-builds/src-noconflict/mode-nginx'
 import ace from 'ace-builds'
 import 'ace-builds/src-noconflict/theme-monokai'
 import extSearchboxUrl from 'ace-builds/src-noconflict/ext-searchbox?url'
-import { computed } from 'vue'
 
 const props = defineProps<{
   content?: string

+ 0 - 1
app/src/components/EnvIndicator/EnvIndicator.vue

@@ -2,7 +2,6 @@
 import { CloseOutlined, DashboardOutlined, DatabaseOutlined } from '@ant-design/icons-vue'
 import { storeToRefs } from 'pinia'
 import { useRouter } from 'vue-router'
-import { computed, watch } from 'vue'
 import { useSettingsStore } from '@/pinia'
 
 const settingsStore = useSettingsStore()

+ 0 - 1
app/src/components/SwitchAppearance/SwitchAppearance.vue

@@ -1,6 +1,5 @@
 <script lang="ts" setup>
 import type { Ref } from 'vue'
-import { computed, inject } from 'vue'
 import VPIconMoon from './icons/VPIconMoon.vue'
 import VPIconSun from './icons/VPIconSun.vue'
 import VPSwitch from '@/components/VPSwitch/VPSwitch.vue'

+ 1 - 1
app/src/routes/index.ts

@@ -131,7 +131,7 @@ export const routes: RouteRecordRaw[] = [
           {
             path: 'list',
             name: 'Certificates List',
-            component: () => import('@/views/certificate/Certificate.vue'),
+            component: () => import('@/views/certificate/CertificateList/Certificate.vue'),
             meta: {
               name: () => $gettext('Certificates List'),
             },

+ 54 - 0
app/src/views/certificate/CertificateList/Certificate.vue

@@ -0,0 +1,54 @@
+<script setup lang="tsx">
+import { CloudUploadOutlined, SafetyCertificateOutlined } from '@ant-design/icons-vue'
+import certColumns from './certColumns'
+import StdTable from '@/components/StdDesign/StdDataDisplay/StdTable.vue'
+import cert from '@/api/cert'
+import WildcardCertificate from '@/views/certificate/WildcardCertificate.vue'
+
+// DO NOT REMOVE THESE LINES
+const no_server_name = computed(() => {
+  return false
+})
+
+provide('no_server_name', no_server_name)
+
+const refWildcard = ref()
+const refTable = ref()
+</script>
+
+<template>
+  <ACard :title="$gettext('Certificates')">
+    <template #extra>
+      <AButton
+        type="link"
+        @click="$router.push('/certificates/import')"
+      >
+        <CloudUploadOutlined />
+        {{ $gettext('Import') }}
+      </AButton>
+
+      <AButton
+        type="link"
+        @click="() => refWildcard.open()"
+      >
+        <SafetyCertificateOutlined />
+        {{ $gettext('Issue wildcard certificate') }}
+      </AButton>
+    </template>
+    <StdTable
+      ref="refTable"
+      :api="cert"
+      :columns="certColumns"
+      disable-view
+      @click-edit="id => $router.push(`/certificates/${id}`)"
+    />
+    <WildcardCertificate
+      ref="refWildcard"
+      @issued="() => refTable.get_list()"
+    />
+  </ACard>
+</template>
+
+<style lang="less" scoped>
+
+</style>

+ 15 - 85
app/src/views/certificate/Certificate.vue → app/src/views/certificate/CertificateList/certColumns.tsx

@@ -1,20 +1,10 @@
-<script setup lang="tsx">
-import { Badge, Tag } from 'ant-design-vue'
 import dayjs from 'dayjs'
-import { CloudUploadOutlined, SafetyCertificateOutlined } from '@ant-design/icons-vue'
-import { input } from '@/components/StdDesign/StdDataEntry'
+import { Badge, Tag } from 'ant-design-vue'
+import type { Column, JSXElements } from '@/components/StdDesign/types'
 import type { customRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
 import { datetime, mask } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
-import cert from '@/api/cert'
-import type { Column, JSXElements } from '@/components/StdDesign/types'
-import type { Cert } from '@/api/cert'
-import { AutoCertState, PrivateKeyTypeMask } from '@/constants'
-import StdTable from '@/components/StdDesign/StdDataDisplay/StdTable.vue'
-import WildcardCertificate from '@/views/certificate/WildcardCertificate.vue'
-
-function notShowInAutoCert(record: Cert) {
-  return record.auto_cert !== AutoCertState.Enable
-}
+import { input } from '@/components/StdDesign/StdDataEntry'
+import { PrivateKeyTypeMask } from '@/constants'
 
 const columns: Column[] = [{
   title: () => $gettext('Name'),
@@ -28,11 +18,9 @@ const columns: Column[] = [{
 
     return h('div', text)
   },
-  edit: {
+  search: {
     type: input,
-    show: notShowInAutoCert,
   },
-  search: true,
 }, {
   title: () => $gettext('Type'),
   dataIndex: 'auto_cert',
@@ -45,17 +33,17 @@ const columns: Column[] = [{
     if (text === true || text === 1) {
       template.push(<Tag bordered={false} color="processing">
         { managed }
-      </Tag>)
+        </Tag>)
     }
     else if (text === 2) {
       template.push(<Tag bordered={false} color="success">
         { sync }
-      </Tag>)
+        </Tag>)
     }
     else {
       template.push(<Tag bordered={false} color="purple">{
-      general }
-      </Tag>)
+          general }
+        </Tag>)
     }
 
     return h('div', template)
@@ -68,29 +56,17 @@ const columns: Column[] = [{
   customRender: mask(PrivateKeyTypeMask),
   sortable: true,
   pithy: true,
-}, {
-  title: () => $gettext('SSL Certificate Path'),
-  dataIndex: 'ssl_certificate_path',
-  edit: {
-    type: input,
-    show: notShowInAutoCert,
-  },
-  hiddenInTable: true,
-}, {
-  title: () => $gettext('SSL Certificate Key Path'),
-  dataIndex: 'ssl_certificate_key_path',
-  edit: {
-    type: input,
-    show: notShowInAutoCert,
-  },
-  hiddenInTable: true,
 }, {
   title: () => $gettext('Status'),
   dataIndex: 'certificate_info',
+  pithy: true,
   customRender: (args: customRender) => {
     const template: JSXElements = []
 
-    const text = args.text?.not_before && args.text?.not_after && !dayjs().isBefore(args.text?.not_before) && !dayjs().isAfter(args.text?.not_after)
+    const text = args.text?.not_before
+      && args.text?.not_after
+      && !dayjs().isBefore(args.text?.not_before)
+      && !dayjs().isAfter(args.text?.not_after)
 
     if (text) {
       template.push(<Badge status="success"/>)
@@ -114,50 +90,4 @@ const columns: Column[] = [{
   dataIndex: 'action',
 }]
 
-// DO NOT REMOVE THESE LINES
-const no_server_name = computed(() => {
-  return false
-})
-
-provide('no_server_name', no_server_name)
-
-const refWildcard = ref()
-const refTable = ref()
-</script>
-
-<template>
-  <ACard :title="$gettext('Certificates')">
-    <template #extra>
-      <AButton
-        type="link"
-        @click="$router.push('/certificates/import')"
-      >
-        <CloudUploadOutlined />
-        {{ $gettext('Import') }}
-      </AButton>
-
-      <AButton
-        type="link"
-        @click="() => refWildcard.open()"
-      >
-        <SafetyCertificateOutlined />
-        {{ $gettext('Issue wildcard certificate') }}
-      </AButton>
-    </template>
-    <StdTable
-      ref="refTable"
-      :api="cert"
-      :columns="columns"
-      disabled-view
-      @click-edit="id => $router.push(`/certificates/${id}`)"
-    />
-    <WildcardCertificate
-      ref="refWildcard"
-      @issued="() => refTable.get_list()"
-    />
-  </ACard>
-</template>
-
-<style lang="less" scoped>
-
-</style>
+export default columns

+ 1 - 3
app/src/views/config/Config.vue

@@ -1,6 +1,4 @@
 <script setup lang="ts">
-import { computed, ref, watch } from 'vue'
-import { useRoute } from 'vue-router'
 import StdTable from '@/components/StdDesign/StdDataDisplay/StdTable.vue'
 import config from '@/api/config'
 import configColumns from '@/views/config/config'
@@ -50,7 +48,7 @@ watch(route, () => {
       :columns="configColumns"
       disable-delete
       disable_search
-      disabled-view
+      disable-view
       row-key="name"
       :get_params="get_params"
       @click-edit="(r, row) => {

+ 1 - 1
app/src/views/domain/DomainList.vue

@@ -108,7 +108,7 @@ watch(route, () => {
       :columns="columns"
       row-key="name"
       disable-delete
-      disabled-view
+      disable-view
       @click-edit="r => $router.push({
         path: `/domain/${r}`,
       })"

+ 2 - 7
app/src/views/domain/cert/Cert.vue

@@ -1,8 +1,7 @@
 <script setup lang="ts">
-import { computed } from 'vue'
 import CertInfo from '@/views/domain/cert/CertInfo.vue'
 import IssueCert from '@/views/domain/cert/IssueCert.vue'
-import ChangeCert from '@/views/domain/cert/ChangeCert.vue'
+import ChangeCert from '@/views/domain/cert/components/ChangeCert/ChangeCert.vue'
 import type { CertificateInfo } from '@/api/cert'
 
 const props = defineProps<{
@@ -12,10 +11,7 @@ const props = defineProps<{
   certInfo?: CertificateInfo
 }>()
 
-const emit = defineEmits(['callback', 'update:enabled'])
-function callback() {
-  emit('callback')
-}
+const emit = defineEmits(['update:enabled'])
 
 const enabled = computed({
   get() {
@@ -42,7 +38,6 @@ const enabled = computed({
     <IssueCert
       v-model:enabled="enabled"
       :config-name="configName"
-      @callback="callback"
     />
   </div>
 </template>

+ 0 - 117
app/src/views/domain/cert/ChangeCert.vue

@@ -1,117 +0,0 @@
-<script setup lang="tsx">
-import { Badge } from 'ant-design-vue'
-import type { ComputedRef, Ref } from 'vue'
-import StdTable from '@/components/StdDesign/StdDataDisplay/StdTable.vue'
-import type { Cert } from '@/api/cert'
-import cert from '@/api/cert'
-import type { customRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
-import { input } from '@/components/StdDesign/StdDataEntry'
-import type { NgxDirective } from '@/api/ngx'
-import type { Column, JSXElements } from '@/components/StdDesign/types'
-
-const current_server_directives = inject('current_server_directives') as ComputedRef<NgxDirective[]>
-const directivesMap = inject('directivesMap') as Ref<Record<string, NgxDirective[]>>
-const visible = ref(false)
-
-const columns: Column[] = [{
-  title: () => $gettext('Name'),
-  dataIndex: 'name',
-  sortable: true,
-  pithy: true,
-  customRender: (args: customRender) => {
-    const { text, record: r } = args
-    if (!text)
-      return h('div', r.domain)
-
-    return h('div', text)
-  },
-  edit: {
-    type: input,
-  },
-  search: true,
-}, {
-  title: () => $gettext('Auto Cert'),
-  dataIndex: 'auto_cert',
-  customRender: (args: customRender) => {
-    const template: JSXElements = []
-    const { text } = args
-    if (text === true || text > 0) {
-      template.push(<Badge status="success"/>)
-      template.push($gettext('Enabled'))
-    }
-    else {
-      template.push(<Badge status="warning"/>)
-      template.push($gettext('Disabled'))
-    }
-
-    return h('div', template)
-  },
-  sortable: true,
-  pithy: true,
-}]
-
-function open() {
-  visible.value = true
-}
-
-const records = ref([]) as Ref<Cert[]>
-
-function ok() {
-  if (directivesMap.value.ssl_certificate?.[0]) {
-    directivesMap.value.ssl_certificate[0].params = records.value[0].ssl_certificate_path
-  }
-  else {
-    current_server_directives?.value.push({
-      directive: 'ssl_certificate',
-      params: records.value[0].ssl_certificate_path,
-    })
-  }
-  if (directivesMap.value.ssl_certificate_key?.[0]) {
-    directivesMap.value.ssl_certificate_key[0].params = records.value[0].ssl_certificate_key_path
-  }
-  else {
-    current_server_directives?.value.push({
-      directive: 'ssl_certificate_key',
-      params: records.value[0].ssl_certificate_key_path,
-    })
-  }
-  visible.value = false
-}
-const selectedKeyBuffer = ref({})
-
-const computedSelectedKeys = computed({
-  get() {
-    return [selectedKeyBuffer.value]
-  },
-  set(v) {
-    selectedKeyBuffer.value = v
-  },
-})
-</script>
-
-<template>
-  <div>
-    <AButton @click="open">
-      {{ $gettext('Change Certificate') }}
-    </AButton>
-    <AModal
-      v-model:open="visible"
-      :title="$gettext('Change Certificate')"
-      :mask="false"
-      @ok="ok"
-    >
-      <StdTable
-        v-model:selected-row-keys="computedSelectedKeys"
-        v-model:selected-rows="records"
-        :api="cert"
-        pithy
-        :columns="columns"
-        selection-type="radio"
-      />
-    </AModal>
-  </div>
-</template>
-
-<style lang="less" scoped>
-
-</style>

+ 1 - 1
app/src/views/domain/cert/IssueCert.vue

@@ -9,7 +9,7 @@ export interface Props {
 
 const props = defineProps<Props>()
 
-const emit = defineEmits(['callback', 'update:enabled'])
+const emit = defineEmits(['update:enabled'])
 
 const issuing_cert = ref(false)
 const obtain_cert = ref()

+ 66 - 0
app/src/views/domain/cert/components/ChangeCert/ChangeCert.vue

@@ -0,0 +1,66 @@
+<script setup lang="ts">
+import type { Ref, WritableComputedRef } from 'vue'
+import StdTable from '@/components/StdDesign/StdDataDisplay/StdTable.vue'
+import type { Cert } from '@/api/cert'
+import cert from '@/api/cert'
+import type { NgxDirective } from '@/api/ngx'
+import certColumns from '@/views/certificate/CertificateList/certColumns'
+
+const current_server_directives = inject('current_server_directives') as WritableComputedRef<NgxDirective[]>
+const visible = ref(false)
+
+function open() {
+  visible.value = true
+}
+
+const records = ref([]) as Ref<Cert[]>
+const selectedKeys = ref([])
+
+async function ok() {
+  // clear all ssl_certificate and ssl_certificate_key
+  current_server_directives.value
+    = current_server_directives.value
+      .filter(v => v.directive !== 'ssl_certificate' && v.directive !== 'ssl_certificate_key')
+
+  records.value.forEach(v => {
+    current_server_directives?.value.push({
+      directive: 'ssl_certificate',
+      params: v.ssl_certificate_path,
+    })
+    current_server_directives?.value.push({
+      directive: 'ssl_certificate_key',
+      params: v.ssl_certificate_key_path,
+    })
+  })
+
+  visible.value = false
+}
+</script>
+
+<template>
+  <div>
+    <AButton @click="open">
+      {{ $gettext('Change Certificate') }}
+    </AButton>
+    <AModal
+      v-model:open="visible"
+      :title="$gettext('Change Certificate')"
+      :mask="false"
+      width="800px"
+      @ok="ok"
+    >
+      <StdTable
+        v-model:selected-row-keys="selectedKeys"
+        v-model:selected-rows="records"
+        :api="cert"
+        pithy
+        :columns="certColumns"
+        selection-type="checkbox"
+      />
+    </AModal>
+  </div>
+</template>
+
+<style lang="less" scoped>
+
+</style>

+ 0 - 1
app/src/views/domain/ngx_conf/LocationEditor.vue

@@ -1,5 +1,4 @@
 <script setup lang="ts">
-import { reactive, ref } from 'vue'
 import { DeleteOutlined, HolderOutlined } from '@ant-design/icons-vue'
 import Draggable from 'vuedraggable'
 import CodeEditor from '@/components/CodeEditor'

+ 12 - 7
app/src/views/domain/ngx_conf/NgxConfigEditor.vue

@@ -65,24 +65,29 @@ function confirm_change_tls(status: CheckedType) {
   })
 }
 
-const current_server_directives = computed(() => {
-  return ngx_config.servers?.[current_server_index.value]?.directives
+const current_server_directives = computed({
+  get() {
+    return ngx_config.servers?.[current_server_index.value]?.directives
+  },
+  set(v) {
+    ngx_config.servers[current_server_index.value].directives = v
+  },
 })
 
 provide('current_server_directives', current_server_directives)
 
 const directivesMap: ComputedRef<Record<string, NgxDirective[]>> = computed(() => {
-  const map: Record<string, NgxDirective[]> = {}
+  const record: Record<string, NgxDirective[]> = {}
 
   current_server_directives.value?.forEach((v, k) => {
     v.idx = k
-    if (map[v.directive])
-      map[v.directive].push(v)
+    if (record[v.directive])
+      record[v.directive].push(v)
     else
-      map[v.directive] = [v]
+      record[v.directive] = [v]
   })
 
-  return map
+  return record
 })
 
 // eslint-disable-next-line sonarjs/cognitive-complexity

+ 0 - 5
app/src/views/domain/ngx_conf/NgxServer.vue

@@ -1,7 +1,5 @@
 <script setup lang="ts">
-
 import { MoreOutlined, PlusOutlined } from '@ant-design/icons-vue'
-import type { ComputedRef, Ref } from 'vue'
 import { Modal } from 'ant-design-vue'
 import LogEntry from '@/views/domain/ngx_conf/LogEntry.vue'
 import ConfigTemplate from '@/views/domain/ngx_conf/config_template/ConfigTemplate.vue'
@@ -21,8 +19,6 @@ withDefaults(defineProps<{
   context: 'http',
 })
 
-const emit = defineEmits(['callback'])
-
 const [modal, ContextHolder] = Modal.useModal()
 
 const current_server_index = inject('current_server_index') as Ref<number>
@@ -131,7 +127,6 @@ provide('ngx_directives', ngx_directives)
               :config-name="ngx_config.name"
               :cert-info="certInfo?.[k]"
               :current-server-index="current_server_index"
-              @callback="emit('callback')"
             />
           </template>
 

+ 0 - 1
app/src/views/other/Install.vue

@@ -1,6 +1,5 @@
 <script setup lang="ts">
 import { Form, message } from 'ant-design-vue'
-import { reactive, ref } from 'vue'
 import { useRouter } from 'vue-router'
 import { DatabaseOutlined, LockOutlined, MailOutlined, UserOutlined } from '@ant-design/icons-vue'
 import SetLanguage from '@/components/SetLanguage/SetLanguage.vue'

+ 0 - 1
app/src/views/preference/AuthSettings.vue

@@ -1,7 +1,6 @@
 <script setup lang="tsx">
 import { message } from 'ant-design-vue'
 import type { Ref } from 'vue'
-import { inject } from 'vue'
 import dayjs from 'dayjs'
 import type { BannedIP } from '@/api/settings'
 import setting from '@/api/settings'

+ 0 - 1
app/src/views/preference/BasicSettings.vue

@@ -1,5 +1,4 @@
 <script setup lang="ts">
-import { inject } from 'vue'
 import Draggable from 'vuedraggable'
 import { DeleteOutlined, HolderOutlined } from '@ant-design/icons-vue'
 import type { Settings } from '@/views/preference/typedef'

+ 0 - 1
app/src/views/preference/LogrotateSettings.vue

@@ -1,5 +1,4 @@
 <script setup lang="ts">
-import { inject } from 'vue'
 import type { Settings } from '@/views/preference/typedef'
 
 const data: Settings = inject('data')!

+ 0 - 1
app/src/views/preference/NginxSettings.vue

@@ -1,5 +1,4 @@
 <script setup lang="ts">
-import { inject } from 'vue'
 import type { Settings } from '@/views/preference/typedef'
 
 const data: Settings = inject('data')!

+ 0 - 1
app/src/views/preference/OpenAISettings.vue

@@ -1,5 +1,4 @@
 <script setup lang="ts">
-import { inject } from 'vue'
 import type { Settings } from '@/views/preference/typedef'
 
 const data: Settings = inject('data')!

+ 1 - 1
app/src/views/stream/StreamList.vue

@@ -129,7 +129,7 @@ function handleAddStream() {
       :columns="columns"
       row-key="name"
       disable-delete
-      disabled-view
+      disable-view
       @click-edit="r => $router.push({
         path: `/stream/${r}`,
       })"