blob: 313b3218166b8479b39951aff6f09e573c3a4a8b [file] [log] [blame]
Yoshie Muranaka37393812020-03-24 15:25:24 -07001<template>
2 <b-container fluid>
3 <page-title />
4 <b-row>
Yoshie Muranakae45f54b2020-03-26 15:23:34 -07005 <b-col xl="9">
6 <!-- Expired certificates banner -->
7 <alert :show="expiredCertificateTypes.length > 0" variant="danger">
8 <template v-if="expiredCertificateTypes.length > 1">
9 {{ $t('pageSslCertificates.alert.certificatesExpiredMessage') }}
10 </template>
11 <template v-else>
12 {{
13 $t('pageSslCertificates.alert.certificateExpiredMessage', {
14 certificate: expiredCertificateTypes[0]
15 })
16 }}
17 </template>
18 </alert>
19 <!-- Expiring certificates banner -->
20 <alert :show="expiringCertificateTypes.length > 0" variant="warning">
21 <template v-if="expiringCertificateTypes.length > 1">
22 {{ $t('pageSslCertificates.alert.certificatesExpiringMessage') }}
23 </template>
24 <template v-else>
25 {{
26 $t('pageSslCertificates.alert.certificateExpiringMessage', {
27 certificate: expiringCertificateTypes[0]
28 })
29 }}
30 </template>
31 </alert>
32 </b-col>
33 </b-row>
34 <b-row>
Yoshie Muranaka37393812020-03-24 15:25:24 -070035 <b-col xl="9" class="text-right">
36 <b-button
37 variant="primary"
38 :disabled="certificatesForUpload.length === 0"
39 @click="initModalUploadCertificate(null)"
40 >
41 <icon-add />
42 {{ $t('pageSslCertificates.addNewCertificate') }}
43 </b-button>
44 </b-col>
45 </b-row>
46 <b-row>
47 <b-col xl="9">
48 <b-table :fields="fields" :items="tableItems">
49 <template v-slot:cell(validFrom)="{ value }">
50 {{ value | formatDate }}
51 </template>
52
53 <template v-slot:cell(validUntil)="{ value }">
Yoshie Muranakae45f54b2020-03-26 15:23:34 -070054 <status-icon
55 v-if="getDaysUntilExpired(value) < 31"
56 :status="getIconStatus(value)"
57 />
Yoshie Muranaka37393812020-03-24 15:25:24 -070058 {{ value | formatDate }}
59 </template>
60
61 <template v-slot:cell(actions)="{ value, item }">
62 <table-row-action
63 v-for="(action, index) in value"
64 :key="index"
65 :value="action.value"
66 :title="action.title"
67 :enabled="action.enabled"
68 @click:tableAction="onTableRowAction($event, item)"
69 >
70 <template v-slot:icon>
71 <icon-replace v-if="action.value === 'replace'" />
72 <icon-trashcan v-if="action.value === 'delete'" />
73 </template>
74 </table-row-action>
75 </template>
76 </b-table>
77 </b-col>
78 </b-row>
79
80 <!-- Modals -->
81 <modal-upload-certificate :certificate="modalCertificate" @ok="onModalOk" />
82 </b-container>
83</template>
84
85<script>
86import IconAdd from '@carbon/icons-vue/es/add--alt/20';
87import IconReplace from '@carbon/icons-vue/es/renew/20';
88import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
89
90import ModalUploadCertificate from './ModalUploadCertificate';
91import PageTitle from '../../../components/Global/PageTitle';
92import TableRowAction from '../../../components/Global/TableRowAction';
Yoshie Muranakae45f54b2020-03-26 15:23:34 -070093import StatusIcon from '../../../components/Global/StatusIcon';
94import Alert from '../../../components/Global/Alert';
Yoshie Muranaka37393812020-03-24 15:25:24 -070095
96import BVToastMixin from '../../../components/Mixins/BVToastMixin';
97
98export default {
99 name: 'SslCertificates',
100 components: {
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700101 Alert,
Yoshie Muranaka37393812020-03-24 15:25:24 -0700102 IconAdd,
103 IconReplace,
104 IconTrashcan,
105 ModalUploadCertificate,
106 PageTitle,
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700107 StatusIcon,
Yoshie Muranaka37393812020-03-24 15:25:24 -0700108 TableRowAction
109 },
110 mixins: [BVToastMixin],
111 data() {
112 return {
113 modalCertificate: null,
114 fields: [
115 {
116 key: 'certificate',
117 label: this.$t('pageSslCertificates.table.certificate')
118 },
119 {
120 key: 'issuedBy',
121 label: this.$t('pageSslCertificates.table.issuedBy')
122 },
123 {
124 key: 'issuedTo',
125 label: this.$t('pageSslCertificates.table.issuedTo')
126 },
127 {
128 key: 'validFrom',
129 label: this.$t('pageSslCertificates.table.validFrom')
130 },
131 {
132 key: 'validUntil',
133 label: this.$t('pageSslCertificates.table.validUntil')
134 },
135 {
136 key: 'actions',
137 label: '',
138 tdClass: 'text-right'
139 }
140 ]
141 };
142 },
143 computed: {
144 certificates() {
145 return this.$store.getters['sslCertificates/allCertificates'];
146 },
147 tableItems() {
148 return this.certificates.map(certificate => {
149 return {
150 ...certificate,
151 actions: [
152 {
153 value: 'replace',
154 title: this.$t('pageSslCertificates.replaceCertificate')
155 },
156 {
157 value: 'delete',
158 title: this.$t('pageSslCertificates.deleteCertificate'),
159 enabled:
160 certificate.type === 'TrustStore Certificate' ? true : false
161 }
162 ]
163 };
164 });
165 },
166 certificatesForUpload() {
167 return this.$store.getters['sslCertificates/availableUploadTypes'];
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700168 },
169 bmcTime() {
170 return this.$store.getters['global/bmcTime'];
171 },
172 expiredCertificateTypes() {
173 return this.certificates.reduce((acc, val) => {
174 const daysUntilExpired = this.getDaysUntilExpired(val.validUntil);
175 if (daysUntilExpired < 1) {
176 acc.push(val.certificate);
177 }
178 return acc;
179 }, []);
180 },
181 expiringCertificateTypes() {
182 return this.certificates.reduce((acc, val) => {
183 const daysUntilExpired = this.getDaysUntilExpired(val.validUntil);
184 if (daysUntilExpired < 31 && daysUntilExpired > 0) {
185 acc.push(val.certificate);
186 }
187 return acc;
188 }, []);
Yoshie Muranaka37393812020-03-24 15:25:24 -0700189 }
190 },
191 created() {
192 this.$store.dispatch('sslCertificates/getCertificates');
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700193 this.$store.dispatch('global/getBmcTime');
Yoshie Muranaka37393812020-03-24 15:25:24 -0700194 },
195 methods: {
196 onTableRowAction(event, rowItem) {
197 switch (event) {
198 case 'replace':
199 this.initModalUploadCertificate(rowItem);
200 break;
201 case 'delete':
202 this.initModalDeleteCertificate(rowItem);
203 break;
204 default:
205 break;
206 }
207 },
208 initModalUploadCertificate(certificate = null) {
209 this.modalCertificate = certificate;
210 this.$bvModal.show('upload-certificate');
211 },
212 initModalDeleteCertificate(certificate) {
213 this.$bvModal
214 .msgBoxConfirm(
215 this.$t('pageSslCertificates.modal.deleteConfirmMessage', {
216 issuedBy: certificate.issuedBy,
217 certificate: certificate.certificate
218 }),
219 {
220 title: this.$t('pageSslCertificates.deleteCertificate'),
221 okTitle: this.$t('global.action.delete')
222 }
223 )
224 .then(deleteConfirmed => {
225 if (deleteConfirmed) this.deleteCertificate(certificate);
226 });
227 },
228 onModalOk({ addNew, file, type, location }) {
229 if (addNew) {
230 // Upload a new certificate
231 this.addNewCertificate(file, type);
232 } else {
233 // Replace an existing certificate
234 this.replaceCertificate(file, type, location);
235 }
236 },
237 addNewCertificate(file, type) {
238 this.$store
239 .dispatch('sslCertificates/addNewCertificate', { file, type })
240 .then(success => this.successToast(success))
241 .catch(({ message }) => this.errorToast(message));
242 },
243 replaceCertificate(file, type, location) {
244 const reader = new FileReader();
245 reader.readAsBinaryString(file);
246 reader.onloadend = event => {
247 const certificateString = event.target.result;
248 this.$store
249 .dispatch('sslCertificates/replaceCertificate', {
250 certificateString,
251 type,
252 location
253 })
254 .then(success => this.successToast(success))
255 .catch(({ message }) => this.errorToast(message));
256 };
257 },
258 deleteCertificate({ type, location }) {
259 this.$store
260 .dispatch('sslCertificates/deleteCertificate', {
261 type,
262 location
263 })
264 .then(success => this.successToast(success))
265 .catch(({ message }) => this.errorToast(message));
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700266 },
267 getDaysUntilExpired(date) {
268 if (this.bmcTime) {
269 const validUntilMs = date.getTime();
270 const currentBmcTimeMs = this.bmcTime.getTime();
271 const oneDayInMs = 24 * 60 * 60 * 1000;
272 return Math.round((validUntilMs - currentBmcTimeMs) / oneDayInMs);
273 }
274 return null;
275 },
276 getIconStatus(date) {
277 const daysUntilExpired = this.getDaysUntilExpired(date);
278 if (daysUntilExpired < 1) {
279 return 'danger';
280 } else if (daysUntilExpired < 31) {
281 return 'warning';
282 }
Yoshie Muranaka37393812020-03-24 15:25:24 -0700283 }
284 }
285};
286</script>