blob: 6d6d789afe4bd18c753eba5dd82b533fa0540ee2 [file] [log] [blame]
Yoshie Muranaka532a4b02020-03-27 11:00:50 -07001<template>
2 <div>
3 <b-modal
4 id="generate-csr"
5 ref="modal"
6 size="lg"
7 no-stacking
8 :title="
9 $t('pageSslCertificates.modal.generateACertificateSigningRequest')
10 "
11 @ok="onOkGenerateCsrModal"
12 @cancel="resetForm"
13 @hidden="$v.$reset()"
14 >
Yoshie Muranakac77fdaf2020-05-04 09:33:51 -070015 <b-form id="generate-csr-form" novalidate @submit.prevent="handleSubmit">
Yoshie Muranaka532a4b02020-03-27 11:00:50 -070016 <b-container fluid>
17 <b-row>
18 <b-col lg="9">
19 <b-row>
20 <b-col lg="6">
21 <b-form-group
22 :label="
23 $t('pageSslCertificates.modal.certificateType') + ' *'
24 "
25 label-for="certificate-type"
26 >
27 <b-form-select
28 id="certificate-type"
29 v-model="form.certificateType"
SurenNewared0df7d22020-07-22 16:41:20 +053030 data-test-id="modalGenerateCsr-select-certificateType"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -070031 :options="certificateOptions"
32 :state="getValidationState($v.form.certificateType)"
33 @input="$v.form.certificateType.$touch()"
34 >
35 <template v-slot:first>
36 <b-form-select-option :value="null" disabled>
37 {{ $t('global.form.selectAnOption') }}
38 </b-form-select-option>
39 </template>
40 </b-form-select>
41 <b-form-invalid-feedback role="alert">
42 {{ $t('global.form.fieldRequired') }}
43 </b-form-invalid-feedback>
44 </b-form-group>
45 </b-col>
46 <b-col lg="6">
47 <b-form-group
48 :label="$t('pageSslCertificates.modal.country') + ' *'"
49 label-for="country"
50 >
51 <b-form-select
52 id="country"
53 v-model="form.country"
SurenNewared0df7d22020-07-22 16:41:20 +053054 data-test-id="modalGenerateCsr-select-country"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -070055 :options="countryOptions"
56 :state="getValidationState($v.form.country)"
57 @input="$v.form.country.$touch()"
58 >
59 <template v-slot:first>
60 <b-form-select-option :value="null" disabled>
61 {{ $t('global.form.selectAnOption') }}
62 </b-form-select-option>
63 </template>
64 </b-form-select>
65 <b-form-invalid-feedback role="alert">
66 {{ $t('global.form.fieldRequired') }}
67 </b-form-invalid-feedback>
68 </b-form-group>
69 </b-col>
70 </b-row>
71 <b-row>
72 <b-col lg="6">
73 <b-form-group
74 :label="$t('pageSslCertificates.modal.state') + ' *'"
75 label-for="state"
76 >
77 <b-form-input
78 id="state"
79 v-model="form.state"
80 type="text"
SurenNewared0df7d22020-07-22 16:41:20 +053081 data-test-id="modalGenerateCsr-input-state"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -070082 :state="getValidationState($v.form.state)"
83 />
84 <b-form-invalid-feedback role="alert">
85 {{ $t('global.form.fieldRequired') }}
86 </b-form-invalid-feedback>
87 </b-form-group>
88 </b-col>
89 <b-col lg="6">
90 <b-form-group
91 :label="$t('pageSslCertificates.modal.city') + ' *'"
92 label-for="city"
93 >
94 <b-form-input
95 id="city"
96 v-model="form.city"
97 type="text"
SurenNewared0df7d22020-07-22 16:41:20 +053098 data-test-id="modalGenerateCsr-input-city"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -070099 :state="getValidationState($v.form.city)"
100 />
101 <b-form-invalid-feedback role="alert">
102 {{ $t('global.form.fieldRequired') }}
103 </b-form-invalid-feedback>
104 </b-form-group>
105 </b-col>
106 </b-row>
107 <b-row>
108 <b-col lg="6">
109 <b-form-group
110 :label="$t('pageSslCertificates.modal.companyName') + ' *'"
111 label-for="company-name"
112 >
113 <b-form-input
114 id="company-name"
115 v-model="form.companyName"
116 type="text"
SurenNewared0df7d22020-07-22 16:41:20 +0530117 data-test-id="modalGenerateCsr-input-companyName"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700118 :state="getValidationState($v.form.companyName)"
119 />
120 <b-form-invalid-feedback role="alert">
121 {{ $t('global.form.fieldRequired') }}
122 </b-form-invalid-feedback>
123 </b-form-group>
124 </b-col>
125 <b-col lg="6">
126 <b-form-group
127 :label="$t('pageSslCertificates.modal.companyUnit') + ' *'"
128 label-for="company-unit"
129 >
130 <b-form-input
131 id="company-unit"
132 v-model="form.companyUnit"
133 type="text"
SurenNewared0df7d22020-07-22 16:41:20 +0530134 data-test-id="modalGenerateCsr-input-companyUnit"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700135 :state="getValidationState($v.form.companyUnit)"
136 />
137 <b-form-invalid-feedback role="alert">
138 {{ $t('global.form.fieldRequired') }}
139 </b-form-invalid-feedback>
140 </b-form-group>
141 </b-col>
142 </b-row>
143 <b-row>
144 <b-col lg="6">
145 <b-form-group
146 :label="$t('pageSslCertificates.modal.commonName') + ' *'"
147 label-for="common-name"
148 >
149 <b-form-input
150 id="common-name"
151 v-model="form.commonName"
152 type="text"
SurenNewared0df7d22020-07-22 16:41:20 +0530153 data-test-id="modalGenerateCsr-input-commonName"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700154 :state="getValidationState($v.form.commonName)"
155 />
156 <b-form-invalid-feedback role="alert">
157 {{ $t('global.form.fieldRequired') }}
158 </b-form-invalid-feedback>
159 </b-form-group>
160 </b-col>
161 <b-col lg="6">
162 <b-form-group
163 :label="$t('pageSslCertificates.modal.challengePassword')"
164 label-for="challenge-password"
165 >
166 <b-form-input
167 id="challenge-password"
168 v-model="form.challengePassword"
169 type="text"
SurenNewared0df7d22020-07-22 16:41:20 +0530170 data-test-id="modalGenerateCsr-input-challengePassword"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700171 />
172 </b-form-group>
173 </b-col>
174 </b-row>
175 <b-row>
176 <b-col lg="6">
177 <b-form-group
178 :label="$t('pageSslCertificates.modal.contactPerson')"
179 label-for="contact-person"
180 >
181 <b-form-input
182 id="contact-person"
183 v-model="form.contactPerson"
184 type="text"
SurenNewared0df7d22020-07-22 16:41:20 +0530185 data-test-id="modalGenerateCsr-input-contactPerson"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700186 />
187 </b-form-group>
188 </b-col>
189 <b-col lg="6">
190 <b-form-group
191 :label="$t('pageSslCertificates.modal.emailAddress')"
192 label-for="email-address"
193 >
194 <b-form-input
195 id="email-address"
196 v-model="form.emailAddress"
197 type="text"
SurenNewared0df7d22020-07-22 16:41:20 +0530198 data-test-id="modalGenerateCsr-input-emailAddress"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700199 />
200 </b-form-group>
201 </b-col>
202 </b-row>
203 <b-row>
204 <b-col lg="12">
205 <b-form-group
206 :label="$t('pageSslCertificates.modal.alternateName')"
207 label-for="alternate-name"
208 >
209 <b-form-text id="alternate-name-help-block">
210 {{
211 $t('pageSslCertificates.modal.alternateNameHelperText')
212 }}
213 </b-form-text>
214 <b-form-tags
215 v-model="form.alternateName"
216 :remove-on-delete="true"
217 :tag-pills="true"
218 input-id="alternate-name"
219 size="lg"
220 separator=" "
221 :input-attrs="{
222 'aria-describedby': 'alternate-name-help-block'
223 }"
224 :duplicate-tag-text="
225 $t('pageSslCertificates.modal.duplicateAlternateName')
226 "
227 placeholder=""
228 >
229 <template v-slot:add-button-text>
230 {{ $t('global.action.add') }} <icon-add />
231 </template>
232 </b-form-tags>
233 </b-form-group>
234 </b-col>
235 </b-row>
236 </b-col>
237 <b-col lg="3">
238 <b-row>
239 <b-col lg="12">
240 <p class="col-form-label">
241 {{ $t('pageSslCertificates.modal.privateKey') }}
242 </p>
243 <b-form-group
244 :label="
245 $t('pageSslCertificates.modal.keyPairAlgorithm') + ' *'
246 "
247 label-for="key-pair-algorithm"
248 >
249 <b-form-select
250 id="key-pair-algorithm"
251 v-model="form.keyPairAlgorithm"
SurenNewared0df7d22020-07-22 16:41:20 +0530252 data-test-id="modalGenerateCsr-select-keyPairAlgorithm"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700253 :options="keyPairAlgorithmOptions"
254 :state="getValidationState($v.form.keyPairAlgorithm)"
255 @input="$v.form.keyPairAlgorithm.$touch()"
256 >
257 <template v-slot:first>
258 <b-form-select-option :value="null" disabled>
259 {{ $t('global.form.selectAnOption') }}
260 </b-form-select-option>
261 </template>
262 </b-form-select>
263 <b-form-invalid-feedback role="alert">
264 {{ $t('global.form.fieldRequired') }}
265 </b-form-invalid-feedback>
266 </b-form-group>
267 </b-col>
268 </b-row>
269 <b-row>
270 <b-col lg="12">
271 <template v-if="$v.form.keyPairAlgorithm.$model === 'EC'">
272 <b-form-group
273 :label="$t('pageSslCertificates.modal.keyCurveId') + ' *'"
274 label-for="key-curve-id"
275 >
276 <b-form-select
277 id="key-curve-id"
278 v-model="form.keyCurveId"
SurenNewared0df7d22020-07-22 16:41:20 +0530279 data-test-id="modalGenerateCsr-select-keyCurveId"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700280 :options="keyCurveIdOptions"
281 :state="getValidationState($v.form.keyCurveId)"
282 @input="$v.form.keyCurveId.$touch()"
283 >
284 <template v-slot:first>
285 <b-form-select-option :value="null" disabled>
286 {{ $t('global.form.selectAnOption') }}
287 </b-form-select-option>
288 </template>
289 </b-form-select>
290 <b-form-invalid-feedback role="alert">
291 {{ $t('global.form.fieldRequired') }}
292 </b-form-invalid-feedback>
293 </b-form-group>
294 </template>
295 <template v-if="$v.form.keyPairAlgorithm.$model === 'RSA'">
296 <b-form-group
297 :label="
298 $t('pageSslCertificates.modal.keyBitLength') + ' *'
299 "
300 label-for="key-bit-length"
301 >
302 <b-form-select
303 id="key-bit-length"
304 v-model="form.keyBitLength"
SurenNewared0df7d22020-07-22 16:41:20 +0530305 data-test-id="modalGenerateCsr-select-keyBitLength"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700306 :options="keyBitLengthOptions"
307 :state="getValidationState($v.form.keyBitLength)"
308 @input="$v.form.keyBitLength.$touch()"
309 >
310 <template v-slot:first>
311 <b-form-select-option :value="null" disabled>
312 {{ $t('global.form.selectAnOption') }}
313 </b-form-select-option>
314 </template>
315 </b-form-select>
316 <b-form-invalid-feedback role="alert">
317 {{ $t('global.form.fieldRequired') }}
318 </b-form-invalid-feedback>
319 </b-form-group>
320 </template>
321 </b-col>
322 </b-row>
323 </b-col>
324 </b-row>
325 </b-container>
326 </b-form>
327 <template v-slot:modal-footer="{ ok, cancel }">
328 <b-button variant="secondary" @click="cancel()">
329 {{ $t('global.action.cancel') }}
330 </b-button>
331 <b-button
332 form="generate-csr-form"
333 type="submit"
334 variant="primary"
SurenNewared0df7d22020-07-22 16:41:20 +0530335 data-test-id="modalGenerateCsr-button-ok"
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700336 @click="ok()"
337 >
338 {{ $t('pageSslCertificates.generateCsr') }}
339 </b-button>
340 </template>
341 </b-modal>
342 <b-modal
343 id="csr-string"
344 no-stacking
345 size="lg"
346 :title="$t('pageSslCertificates.modal.certificateSigningRequest')"
347 @hidden="onHiddenCsrStringModal"
348 >
349 {{ csrString }}
350 <template v-slot:modal-footer>
351 <b-btn variant="secondary" @click="copyCsrString">
352 <template v-if="csrStringCopied">
353 <icon-checkmark />
354 {{ $t('global.status.copied') }}
355 </template>
356 <template v-else>
357 {{ $t('global.action.copy') }}
358 </template>
359 </b-btn>
360 <a
361 :href="`data:text/json;charset=utf-8,${csrString}`"
362 download="certificate.txt"
363 class="btn btn-primary"
364 >
365 {{ $t('global.action.download') }}
366 </a>
367 </template>
368 </b-modal>
369 </div>
370</template>
371
372<script>
373import IconAdd from '@carbon/icons-vue/es/add--alt/20';
374import IconCheckmark from '@carbon/icons-vue/es/checkmark/20';
375
376import { required, requiredIf } from 'vuelidate/lib/validators';
377
378import { COUNTRY_LIST } from './CsrCountryCodes';
379import { CERTIFICATE_TYPES } from '../../../store/modules/AccessControl/SslCertificatesStore';
380import BVToastMixin from '../../../components/Mixins/BVToastMixin';
381import VuelidateMixin from '../../../components/Mixins/VuelidateMixin.js';
382
383export default {
384 name: 'ModalGenerateCsr',
385 components: { IconAdd, IconCheckmark },
386 mixins: [BVToastMixin, VuelidateMixin],
387 data() {
388 return {
389 form: {
390 certificateType: null,
391 country: null,
392 state: null,
393 city: null,
394 companyName: null,
395 companyUnit: null,
396 commonName: null,
397 challengePassword: null,
398 contactPerson: null,
399 emailAddress: null,
400 alternateName: [],
401 keyPairAlgorithm: null,
402 keyCurveId: null,
403 keyBitLength: null
404 },
405 certificateOptions: CERTIFICATE_TYPES.reduce((arr, cert) => {
406 if (cert.type === 'TrustStore Certificate') return arr;
407 arr.push({
408 text: cert.label,
409 value: cert.type
410 });
411 return arr;
412 }, []),
413 countryOptions: COUNTRY_LIST.map(country => ({
414 text: country.label,
415 value: country.code
416 })),
417 keyPairAlgorithmOptions: ['EC', 'RSA'],
418 keyCurveIdOptions: ['prime256v1', 'secp521r1', 'secp384r1'],
419 keyBitLengthOptions: [2048],
420 csrString: '',
421 csrStringCopied: false
422 };
423 },
424 validations: {
425 form: {
426 certificateType: { required },
427 country: { required },
428 state: { required },
429 city: { required },
430 companyName: { required },
431 companyUnit: { required },
432 commonName: { required },
433 challengePassword: {},
434 contactPerson: {},
435 emailAddress: {},
436 alternateName: {},
437 keyPairAlgorithm: { required },
438 keyCurveId: {
439 reuired: requiredIf(function(form) {
440 return form.keyPairAlgorithm === 'EC';
441 })
442 },
443 keyBitLength: {
444 reuired: requiredIf(function(form) {
445 return form.keyPairAlgorithm === 'RSA';
446 })
447 }
448 }
449 },
450 methods: {
451 handleSubmit() {
452 this.$v.$touch();
453 if (this.$v.$invalid) return;
454 this.$store
455 .dispatch('sslCertificates/generateCsr', this.form)
456 .then(({ data: { CSRString } }) => {
457 this.csrString = CSRString;
458 this.$bvModal.show('csr-string');
459 this.$v.$reset();
460 });
461 },
462 resetForm() {
463 for (let key of Object.keys(this.form)) {
464 if (key === 'alternateName') {
465 this.form[key] = [];
466 } else {
467 this.form[key] = null;
468 }
469 }
470 },
471 onOkGenerateCsrModal(bvModalEvt) {
472 // prevent modal close
473 bvModalEvt.preventDefault();
474 this.handleSubmit();
475 },
476 onHiddenCsrStringModal() {
477 this.csrString = '';
478 this.resetForm();
479 },
480 copyCsrString(bvModalEvt) {
481 // prevent modal close
482 bvModalEvt.preventDefault();
483 navigator.clipboard.writeText(this.csrString).then(() => {
484 // Show copied text for 5 seconds
485 this.csrStringCopied = true;
486 setTimeout(() => {
487 this.csrStringCopied = false;
488 }, 5000 /*5 seconds*/);
489 });
490 }
491 }
492};
493</script>