RemoveCert.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <script setup lang="ts">
  2. import { message } from 'ant-design-vue'
  3. import cert from '@/api/cert'
  4. import websocket from '@/lib/websocket'
  5. const props = defineProps<{
  6. id: number
  7. }>()
  8. const emit = defineEmits(['removed'])
  9. const modalVisible = ref(false)
  10. const confirmLoading = ref(false)
  11. const shouldRevoke = ref(false)
  12. const revokeInput = ref('')
  13. // Handle certificate deletion
  14. function handleDelete() {
  15. // Open the combined modal directly
  16. modalVisible.value = true
  17. }
  18. // Handle confirmation
  19. function handleConfirm() {
  20. // If revocation is checked but confirmation text is not correct
  21. if (shouldRevoke.value && revokeInput.value !== $gettext('Revoke')) {
  22. message.error($gettext('Please type "Revoke" to confirm'))
  23. return
  24. }
  25. confirmLoading.value = true
  26. if (shouldRevoke.value) {
  27. // Revoke certificate using WebSocket
  28. const ws = websocket(`/api/certs/${props.id}/revoke`, false)
  29. ws.onmessage = m => {
  30. const response = JSON.parse(m.data)
  31. if (response.status === 'success') {
  32. message.success($gettext('Certificate removed successfully'))
  33. // Close modal and refresh list
  34. modalVisible.value = false
  35. confirmLoading.value = false
  36. emit('removed')
  37. }
  38. else if (response.status === 'error') {
  39. message.error(response.message || $gettext('Failed to revoke certificate'))
  40. confirmLoading.value = false
  41. }
  42. }
  43. ws.onerror = () => {
  44. message.error($gettext('WebSocket connection error'))
  45. confirmLoading.value = false
  46. }
  47. }
  48. else {
  49. // Only remove certificate from database
  50. cert.destroy(props.id).then(() => {
  51. message.success($gettext('Certificate removed successfully'))
  52. modalVisible.value = false
  53. confirmLoading.value = false
  54. emit('removed')
  55. }).catch(error => {
  56. message.error(error.message || $gettext('Failed to delete certificate'))
  57. confirmLoading.value = false
  58. })
  59. }
  60. }
  61. // Handle modal cancel
  62. function handleCancel() {
  63. modalVisible.value = false
  64. shouldRevoke.value = false
  65. revokeInput.value = ''
  66. }
  67. </script>
  68. <template>
  69. <div class="inline-block">
  70. <AButton
  71. type="link"
  72. size="small"
  73. @click="handleDelete"
  74. >
  75. {{ $gettext('Delete') }}
  76. </AButton>
  77. <AModal
  78. v-model:open="modalVisible"
  79. :title="$gettext('Delete Certificate')"
  80. :confirm-loading="confirmLoading"
  81. :ok-button-props="{
  82. disabled: (shouldRevoke && revokeInput !== $gettext('Revoke')),
  83. }"
  84. @ok="handleConfirm"
  85. @cancel="handleCancel"
  86. >
  87. <AAlert
  88. type="warning"
  89. show-icon
  90. :message="$gettext('This operation will only remove the certificate from the database. The certificate files on the file system will not be deleted.')"
  91. class="mb-4"
  92. />
  93. <div class="mb-4">
  94. <ACheckbox v-model:checked="shouldRevoke">
  95. {{ $gettext('Revoke this certificate') }}
  96. </ACheckbox>
  97. </div>
  98. <div v-if="shouldRevoke">
  99. <AAlert
  100. type="error"
  101. show-icon
  102. :message="$gettext('Revoking a certificate will affect any services currently using it. This action cannot be undone.')"
  103. class="mb-4"
  104. />
  105. <p>{{ $gettext('To confirm revocation, please type "Revoke" in the field below:') }}</p>
  106. <AInput v-model:value="revokeInput" />
  107. </div>
  108. </AModal>
  109. </div>
  110. </template>