blob: 29c1436effa77a34751a1cdd4b6d160e4e067bb7 [file] [log] [blame]
Yoshie Muranaka37393812020-03-24 15:25:24 -07001<template>
Yoshie Muranaka3111b6f2020-04-21 19:48:38 -07002 <b-container fluid="xl">
Yoshie Muranaka37393812020-03-24 15:25:24 -07003 <page-title />
4 <b-row>
Yoshie Muranaka3111b6f2020-04-21 19:48:38 -07005 <b-col xl="11">
Yoshie Muranakae45f54b2020-03-26 15:23:34 -07006 <!-- Expired certificates banner -->
7 <alert :show="expiredCertificateTypes.length > 0" variant="danger">
8 <template v-if="expiredCertificateTypes.length > 1">
Sandeepa Singhb4406162021-07-26 15:05:39 +05309 {{ $t('pageCertificates.alert.certificatesExpiredMessage') }}
Yoshie Muranakae45f54b2020-03-26 15:23:34 -070010 </template>
11 <template v-else>
12 {{
Sandeepa Singhb4406162021-07-26 15:05:39 +053013 $t('pageCertificates.alert.certificateExpiredMessage', {
Derick Montague602e98a2020-10-21 16:20:00 -050014 certificate: expiredCertificateTypes[0],
Yoshie Muranakae45f54b2020-03-26 15:23:34 -070015 })
16 }}
17 </template>
18 </alert>
19 <!-- Expiring certificates banner -->
20 <alert :show="expiringCertificateTypes.length > 0" variant="warning">
21 <template v-if="expiringCertificateTypes.length > 1">
Sandeepa Singhb4406162021-07-26 15:05:39 +053022 {{ $t('pageCertificates.alert.certificatesExpiringMessage') }}
Yoshie Muranakae45f54b2020-03-26 15:23:34 -070023 </template>
24 <template v-else>
25 {{
Sandeepa Singhb4406162021-07-26 15:05:39 +053026 $t('pageCertificates.alert.certificateExpiringMessage', {
Derick Montague602e98a2020-10-21 16:20:00 -050027 certificate: expiringCertificateTypes[0],
Yoshie Muranakae45f54b2020-03-26 15:23:34 -070028 })
29 }}
30 </template>
31 </alert>
32 </b-col>
33 </b-row>
34 <b-row>
jason westoverd36ac8a2025-11-03 20:58:59 -060035 <b-col xl="11" class="text-end">
SurenNewared0df7d22020-07-22 16:41:20 +053036 <b-button
Sandeepa Singhb4406162021-07-26 15:05:39 +053037 data-test-id="certificates-button-generateCsr"
SurenNewared0df7d22020-07-22 16:41:20 +053038 variant="link"
jason westoverd36ac8a2025-11-03 20:58:59 -060039 @click="showCsr = true"
SurenNewared0df7d22020-07-22 16:41:20 +053040 >
Yoshie Muranaka532a4b02020-03-27 11:00:50 -070041 <icon-add />
Sandeepa Singhb4406162021-07-26 15:05:39 +053042 {{ $t('pageCertificates.generateCsr') }}
Yoshie Muranaka532a4b02020-03-27 11:00:50 -070043 </b-button>
Yoshie Muranaka37393812020-03-24 15:25:24 -070044 <b-button
45 variant="primary"
46 :disabled="certificatesForUpload.length === 0"
47 @click="initModalUploadCertificate(null)"
48 >
49 <icon-add />
Sandeepa Singhb4406162021-07-26 15:05:39 +053050 {{ $t('pageCertificates.addNewCertificate') }}
Yoshie Muranaka37393812020-03-24 15:25:24 -070051 </b-button>
52 </b-col>
53 </b-row>
54 <b-row>
Yoshie Muranaka3111b6f2020-04-21 19:48:38 -070055 <b-col xl="11">
SurenNeware307382e2020-07-27 20:45:14 +053056 <b-table
57 responsive="md"
58 show-empty
Sukanya Pandeyfde429e2020-09-14 20:48:39 +053059 hover
jason westoverd36ac8a2025-11-03 20:58:59 -060060 thead-class="table-light"
Kenneth Fullbright41057852021-12-27 16:19:37 -060061 :busy="isBusy"
SurenNeware307382e2020-07-27 20:45:14 +053062 :fields="fields"
63 :items="tableItems"
64 :empty-text="$t('global.table.emptyMessage')"
65 >
Derick Montague602e98a2020-10-21 16:20:00 -050066 <template #cell(validFrom)="{ value }">
Surya Vde23ea22024-07-11 15:19:46 +053067 {{ $filters.formatDate(value) }}
Yoshie Muranaka37393812020-03-24 15:25:24 -070068 </template>
69
Derick Montague602e98a2020-10-21 16:20:00 -050070 <template #cell(validUntil)="{ value }">
Yoshie Muranakae45f54b2020-03-26 15:23:34 -070071 <status-icon
72 v-if="getDaysUntilExpired(value) < 31"
73 :status="getIconStatus(value)"
74 />
Surya Vde23ea22024-07-11 15:19:46 +053075 {{ $filters.formatDate(value) }}
Yoshie Muranaka37393812020-03-24 15:25:24 -070076 </template>
77
Derick Montague602e98a2020-10-21 16:20:00 -050078 <template #cell(actions)="{ value, item }">
Yoshie Muranaka37393812020-03-24 15:25:24 -070079 <table-row-action
80 v-for="(action, index) in value"
81 :key="index"
82 :value="action.value"
83 :title="action.title"
84 :enabled="action.enabled"
Sukanya Pandeyedb8a772020-10-29 11:33:42 +053085 @click-table-action="onTableRowAction($event, item)"
Yoshie Muranaka37393812020-03-24 15:25:24 -070086 >
Derick Montague602e98a2020-10-21 16:20:00 -050087 <template #icon>
Yoshie Muranaka37393812020-03-24 15:25:24 -070088 <icon-replace v-if="action.value === 'replace'" />
89 <icon-trashcan v-if="action.value === 'delete'" />
90 </template>
91 </table-row-action>
92 </template>
93 </b-table>
94 </b-col>
95 </b-row>
96
97 <!-- Modals -->
jason westoverd36ac8a2025-11-03 20:58:59 -060098 <modal-upload-certificate
99 v-model="showUpload"
100 :certificate="modalCertificate"
101 @ok="onModalOk"
102 />
103 <modal-generate-csr v-model="showCsr" />
Yoshie Muranaka37393812020-03-24 15:25:24 -0700104 </b-container>
105</template>
106
107<script>
108import IconAdd from '@carbon/icons-vue/es/add--alt/20';
109import IconReplace from '@carbon/icons-vue/es/renew/20';
110import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
111
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700112import ModalGenerateCsr from './ModalGenerateCsr';
Yoshie Muranaka37393812020-03-24 15:25:24 -0700113import ModalUploadCertificate from './ModalUploadCertificate';
SurenNeware5e25e282020-07-08 15:57:23 +0530114import PageTitle from '@/components/Global/PageTitle';
115import TableRowAction from '@/components/Global/TableRowAction';
116import StatusIcon from '@/components/Global/StatusIcon';
117import Alert from '@/components/Global/Alert';
Yoshie Muranaka37393812020-03-24 15:25:24 -0700118
SurenNeware5e25e282020-07-08 15:57:23 +0530119import BVToastMixin from '@/components/Mixins/BVToastMixin';
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700120import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
Surya Vde23ea22024-07-11 15:19:46 +0530121import { useI18n } from 'vue-i18n';
122import i18n from '@/i18n';
jason westoverd36ac8a2025-11-03 20:58:59 -0600123import { useModal } from 'bootstrap-vue-next';
Yoshie Muranaka37393812020-03-24 15:25:24 -0700124
125export default {
Sandeepa Singhb4406162021-07-26 15:05:39 +0530126 name: 'Certificates',
Yoshie Muranaka37393812020-03-24 15:25:24 -0700127 components: {
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700128 Alert,
Yoshie Muranaka37393812020-03-24 15:25:24 -0700129 IconAdd,
130 IconReplace,
131 IconTrashcan,
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700132 ModalGenerateCsr,
Yoshie Muranaka37393812020-03-24 15:25:24 -0700133 ModalUploadCertificate,
134 PageTitle,
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700135 StatusIcon,
Derick Montague602e98a2020-10-21 16:20:00 -0500136 TableRowAction,
Yoshie Muranaka37393812020-03-24 15:25:24 -0700137 },
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700138 mixins: [BVToastMixin, LoadingBarMixin],
Derick Montague602e98a2020-10-21 16:20:00 -0500139 beforeRouteLeave(to, from, next) {
140 this.hideLoader();
141 next();
142 },
jason westoverd36ac8a2025-11-03 20:58:59 -0600143 setup() {
144 const bvModal = useModal();
145 return { bvModal };
146 },
Yoshie Muranaka37393812020-03-24 15:25:24 -0700147 data() {
148 return {
Surya Vde23ea22024-07-11 15:19:46 +0530149 $t: useI18n().t,
Kenneth Fullbright41057852021-12-27 16:19:37 -0600150 isBusy: true,
Yoshie Muranaka37393812020-03-24 15:25:24 -0700151 modalCertificate: null,
jason westoverd36ac8a2025-11-03 20:58:59 -0600152 showUpload: false,
153 showCsr: false,
Damian Celico31fb2b92022-06-27 16:43:21 +0200154 fileTypeCorrect: undefined,
Yoshie Muranaka37393812020-03-24 15:25:24 -0700155 fields: [
156 {
157 key: 'certificate',
Surya Vde23ea22024-07-11 15:19:46 +0530158 label: i18n.global.t('pageCertificates.table.certificate'),
Yoshie Muranaka37393812020-03-24 15:25:24 -0700159 },
160 {
161 key: 'issuedBy',
Surya Vde23ea22024-07-11 15:19:46 +0530162 label: i18n.global.t('pageCertificates.table.issuedBy'),
Yoshie Muranaka37393812020-03-24 15:25:24 -0700163 },
164 {
165 key: 'issuedTo',
Surya Vde23ea22024-07-11 15:19:46 +0530166 label: i18n.global.t('pageCertificates.table.issuedTo'),
Yoshie Muranaka37393812020-03-24 15:25:24 -0700167 },
168 {
169 key: 'validFrom',
Surya Vde23ea22024-07-11 15:19:46 +0530170 label: i18n.global.t('pageCertificates.table.validFrom'),
Yoshie Muranaka37393812020-03-24 15:25:24 -0700171 },
172 {
173 key: 'validUntil',
Surya Vde23ea22024-07-11 15:19:46 +0530174 label: i18n.global.t('pageCertificates.table.validUntil'),
Yoshie Muranaka37393812020-03-24 15:25:24 -0700175 },
176 {
177 key: 'actions',
178 label: '',
jason westoverd36ac8a2025-11-03 20:58:59 -0600179 tdClass: 'text-end text-nowrap',
Derick Montague602e98a2020-10-21 16:20:00 -0500180 },
181 ],
Yoshie Muranaka37393812020-03-24 15:25:24 -0700182 };
183 },
184 computed: {
185 certificates() {
Sandeepa Singhb4406162021-07-26 15:05:39 +0530186 return this.$store.getters['certificates/allCertificates'];
Yoshie Muranaka37393812020-03-24 15:25:24 -0700187 },
188 tableItems() {
Derick Montague602e98a2020-10-21 16:20:00 -0500189 return this.certificates.map((certificate) => {
Yoshie Muranaka37393812020-03-24 15:25:24 -0700190 return {
191 ...certificate,
192 actions: [
193 {
194 value: 'replace',
Surya Vde23ea22024-07-11 15:19:46 +0530195 title: i18n.global.t('pageCertificates.replaceCertificate'),
Yoshie Muranaka37393812020-03-24 15:25:24 -0700196 },
197 {
198 value: 'delete',
Surya Vde23ea22024-07-11 15:19:46 +0530199 title: i18n.global.t('pageCertificates.deleteCertificate'),
Yoshie Muranaka37393812020-03-24 15:25:24 -0700200 enabled:
Derick Montague602e98a2020-10-21 16:20:00 -0500201 certificate.type === 'TrustStore Certificate' ? true : false,
202 },
203 ],
Yoshie Muranaka37393812020-03-24 15:25:24 -0700204 };
205 });
206 },
207 certificatesForUpload() {
Sandeepa Singhb4406162021-07-26 15:05:39 +0530208 return this.$store.getters['certificates/availableUploadTypes'];
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700209 },
210 bmcTime() {
211 return this.$store.getters['global/bmcTime'];
212 },
213 expiredCertificateTypes() {
214 return this.certificates.reduce((acc, val) => {
215 const daysUntilExpired = this.getDaysUntilExpired(val.validUntil);
216 if (daysUntilExpired < 1) {
217 acc.push(val.certificate);
218 }
219 return acc;
220 }, []);
221 },
222 expiringCertificateTypes() {
223 return this.certificates.reduce((acc, val) => {
224 const daysUntilExpired = this.getDaysUntilExpired(val.validUntil);
225 if (daysUntilExpired < 31 && daysUntilExpired > 0) {
226 acc.push(val.certificate);
227 }
228 return acc;
229 }, []);
Derick Montague602e98a2020-10-21 16:20:00 -0500230 },
Yoshie Muranaka37393812020-03-24 15:25:24 -0700231 },
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700232 async created() {
233 this.startLoader();
234 await this.$store.dispatch('global/getBmcTime');
Kenneth Fullbright41057852021-12-27 16:19:37 -0600235 this.$store.dispatch('certificates/getCertificates').finally(() => {
236 this.endLoader();
237 this.isBusy = false;
238 });
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700239 },
Yoshie Muranaka37393812020-03-24 15:25:24 -0700240 methods: {
241 onTableRowAction(event, rowItem) {
242 switch (event) {
243 case 'replace':
244 this.initModalUploadCertificate(rowItem);
245 break;
246 case 'delete':
247 this.initModalDeleteCertificate(rowItem);
248 break;
249 default:
250 break;
251 }
252 },
253 initModalUploadCertificate(certificate = null) {
254 this.modalCertificate = certificate;
jason westoverd36ac8a2025-11-03 20:58:59 -0600255 this.showUpload = true;
Yoshie Muranaka37393812020-03-24 15:25:24 -0700256 },
257 initModalDeleteCertificate(certificate) {
jason westoverd36ac8a2025-11-03 20:58:59 -0600258 this.confirmDialog(
259 i18n.global.t('pageCertificates.modal.deleteConfirmMessage', {
260 issuedBy: certificate.issuedBy,
261 certificate: certificate.certificate,
262 }),
263 {
264 title: i18n.global.t('pageCertificates.deleteCertificate'),
265 okTitle: i18n.global.t('global.action.delete'),
266 cancelTitle: i18n.global.t('global.action.cancel'),
267 autoFocusButton: 'ok',
268 },
269 ).then((deleteConfirmed) => {
270 if (deleteConfirmed) this.deleteCertificate(certificate);
271 });
Yoshie Muranaka37393812020-03-24 15:25:24 -0700272 },
273 onModalOk({ addNew, file, type, location }) {
274 if (addNew) {
275 // Upload a new certificate
Damian Celico31fb2b92022-06-27 16:43:21 +0200276 this.fileTypeCorrect = this.getIsFileTypeCorrect(file);
277 if (this.fileTypeCorrect) {
278 this.addNewCertificate(file, type);
Damian Celico713dae02022-11-14 23:06:55 +0100279 } else {
280 this.errorToast(
Surya Vde23ea22024-07-11 15:19:46 +0530281 i18n.global.t(
282 'pageCertificates.alert.incorrectCertificateFileType',
283 ),
Damian Celico713dae02022-11-14 23:06:55 +0100284 {
Surya Vde23ea22024-07-11 15:19:46 +0530285 title: i18n.global.t(
286 'pageCertificates.toast.errorAddCertificate',
287 ),
Ed Tanous81323992024-02-27 11:26:24 -0800288 },
Damian Celico713dae02022-11-14 23:06:55 +0100289 );
Damian Celico31fb2b92022-06-27 16:43:21 +0200290 }
Yoshie Muranaka37393812020-03-24 15:25:24 -0700291 } else {
292 // Replace an existing certificate
293 this.replaceCertificate(file, type, location);
294 }
295 },
296 addNewCertificate(file, type) {
Damian Celico31fb2b92022-06-27 16:43:21 +0200297 if (this.fileTypeCorrect === true) {
298 this.startLoader();
299 this.$store
300 .dispatch('certificates/addNewCertificate', { file, type })
301 .then((success) => this.successToast(success))
302 .catch(({ message }) => this.errorToast(message))
303 .finally(() => this.endLoader());
304 }
Yoshie Muranaka37393812020-03-24 15:25:24 -0700305 },
306 replaceCertificate(file, type, location) {
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700307 this.startLoader();
Yoshie Muranaka37393812020-03-24 15:25:24 -0700308 const reader = new FileReader();
309 reader.readAsBinaryString(file);
Derick Montague602e98a2020-10-21 16:20:00 -0500310 reader.onloadend = (event) => {
Yoshie Muranaka37393812020-03-24 15:25:24 -0700311 const certificateString = event.target.result;
312 this.$store
Sandeepa Singhb4406162021-07-26 15:05:39 +0530313 .dispatch('certificates/replaceCertificate', {
Yoshie Muranaka37393812020-03-24 15:25:24 -0700314 certificateString,
315 type,
Derick Montague602e98a2020-10-21 16:20:00 -0500316 location,
Yoshie Muranaka37393812020-03-24 15:25:24 -0700317 })
Derick Montague602e98a2020-10-21 16:20:00 -0500318 .then((success) => this.successToast(success))
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700319 .catch(({ message }) => this.errorToast(message))
320 .finally(() => this.endLoader());
Yoshie Muranaka37393812020-03-24 15:25:24 -0700321 };
322 },
323 deleteCertificate({ type, location }) {
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700324 this.startLoader();
Yoshie Muranaka37393812020-03-24 15:25:24 -0700325 this.$store
Sandeepa Singhb4406162021-07-26 15:05:39 +0530326 .dispatch('certificates/deleteCertificate', {
Yoshie Muranaka37393812020-03-24 15:25:24 -0700327 type,
Derick Montague602e98a2020-10-21 16:20:00 -0500328 location,
Yoshie Muranaka37393812020-03-24 15:25:24 -0700329 })
Derick Montague602e98a2020-10-21 16:20:00 -0500330 .then((success) => this.successToast(success))
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700331 .catch(({ message }) => this.errorToast(message))
332 .finally(() => this.endLoader());
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700333 },
334 getDaysUntilExpired(date) {
335 if (this.bmcTime) {
336 const validUntilMs = date.getTime();
337 const currentBmcTimeMs = this.bmcTime.getTime();
338 const oneDayInMs = 24 * 60 * 60 * 1000;
339 return Math.round((validUntilMs - currentBmcTimeMs) / oneDayInMs);
340 }
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700341 return new Date();
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700342 },
343 getIconStatus(date) {
344 const daysUntilExpired = this.getDaysUntilExpired(date);
345 if (daysUntilExpired < 1) {
346 return 'danger';
347 } else if (daysUntilExpired < 31) {
348 return 'warning';
349 }
Derick Montague602e98a2020-10-21 16:20:00 -0500350 },
Damian Celico31fb2b92022-06-27 16:43:21 +0200351 getIsFileTypeCorrect(file) {
352 const fileTypeExtension = file.name.split('.').pop();
353 return fileTypeExtension === 'pem';
354 },
jason westoverd36ac8a2025-11-03 20:58:59 -0600355 confirmDialog(message, options = {}) {
356 return this.$confirm({ message, ...options });
357 },
Derick Montague602e98a2020-10-21 16:20:00 -0500358 },
Yoshie Muranaka37393812020-03-24 15:25:24 -0700359};
360</script>