diff options
author | Yoshie Muranaka <yoshiemuranaka@gmail.com> | 2020-03-27 21:00:50 +0300 |
---|---|---|
committer | Yoshie Muranaka <yoshiemuranaka@gmail.com> | 2020-04-09 17:27:04 +0300 |
commit | 532a4b033669497d972683320e3d1d6dde1943f6 (patch) | |
tree | 894243478cd356256b89d102425e1a6ac0174715 | |
parent | d0d9215bbb3c5b56d682abffb5abb916ff9d4387 (diff) | |
download | webui-vue-532a4b033669497d972683320e3d1d6dde1943f6.tar.xz |
Add generate CSR to SSL certificates page
Adds ability to generate, then download or copy a CSR from the GUI
- Import FormTagsPlugin to use for alternate names field
Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: I060e8d7917a79dafbfb67c758f5baa4a36ab86ae
-rw-r--r-- | src/assets/styles/_badge.scss | 11 | ||||
-rw-r--r-- | src/assets/styles/_form-components.scss | 15 | ||||
-rw-r--r-- | src/assets/styles/_obmc-custom.scss | 1 | ||||
-rw-r--r-- | src/locales/en-US.json | 277 | ||||
-rw-r--r-- | src/main.js | 6 | ||||
-rw-r--r-- | src/store/modules/AccessControl/SslCertificatesStore.js | 48 | ||||
-rw-r--r-- | src/views/AccessControl/SslCertificates/CsrCountryCodes.js | 345 | ||||
-rw-r--r-- | src/views/AccessControl/SslCertificates/ModalGenerateCsr.vue | 479 | ||||
-rw-r--r-- | src/views/AccessControl/SslCertificates/SslCertificates.vue | 11 |
9 files changed, 1188 insertions, 5 deletions
diff --git a/src/assets/styles/_badge.scss b/src/assets/styles/_badge.scss new file mode 100644 index 00000000..99c758af --- /dev/null +++ b/src/assets/styles/_badge.scss @@ -0,0 +1,11 @@ +.badge-pill { + // Need to explicitly set border-radius + // for pill variant because global $enable-rounded + // Boostrap setting removes rounded pill style + border-radius: 10rem; +} + +.badge-primary { + background-color: $info-light; + color: $info; +}
\ No newline at end of file diff --git a/src/assets/styles/_form-components.scss b/src/assets/styles/_form-components.scss index e7a7b0c9..d1fe7854 100644 --- a/src/assets/styles/_form-components.scss +++ b/src/assets/styles/_form-components.scss @@ -34,4 +34,19 @@ color: $gray-700!important; } } +} + +.b-form-tag-remove { + // X button to remove tag + font-weight: normal; +} + +.b-form-tags-button { + // Add button inside input field + white-space: nowrap; + margin-right: -$spacer; + &.btn-link-primary { + color: $primary; + fill: currentColor; + } }
\ No newline at end of file diff --git a/src/assets/styles/_obmc-custom.scss b/src/assets/styles/_obmc-custom.scss index 2a8d896a..544e5858 100644 --- a/src/assets/styles/_obmc-custom.scss +++ b/src/assets/styles/_obmc-custom.scss @@ -40,6 +40,7 @@ @import "~bootstrap-vue/src/index.scss"; @import "./alerts"; +@import "./badge"; @import "./buttons"; @import "./form-components"; @import "./modal"; diff --git a/src/locales/en-US.json b/src/locales/en-US.json index b243f539..277db0b8 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -3,9 +3,11 @@ "action": { "add": "Add", "confirm": "Confirm", + "copy": "Copy", "cancel": "Cancel", "delete": "Delete", "disable": "Disable", + "download": "Download", "enable": "Enable", "replace": "Replace", "save": "Save", @@ -24,6 +26,7 @@ "valueMustBeBetween": "Value must be between %{min} – %{max}" }, "status": { + "copied": "Copied", "disabled": "Disabled", "enabled": "Enabled", "error": "Error", @@ -237,6 +240,7 @@ "addNewCertificate": "Add new certificate", "caCertificate": "CA Certificate", "deleteCertificate": "Delete certificate", + "generateCsr": "Generate CSR", "httpsCertificate": "HTTPS Certificate", "ldapCertificate": "LDAP Certificate", "replaceCertificate": "Replace certificate", @@ -247,9 +251,27 @@ "certificatesExpiringMessage": "Some certificates are expiring soon. Consider replacing them with new certificates." }, "modal": { - "certificateType": "Certificate type", + "alternateName": "Alternate name", + "alternateNameHelperText": "Add multiple alternate names separated by space", "certificateFile": "Certificate file", - "deleteConfirmMessage": "Are you sure you want to delete '%{certificate}' issued by %{issuedBy}? This action cannot be undone." + "certificateSigningRequest": "Certificate Signing Request (CSR)", + "certificateType": "Certificate type", + "challengePassword": "Challenge password", + "city": "City", + "commonName": "Common name", + "companyName": "Company name", + "companyUnit": "Company unit", + "contactPerson": "Contact person", + "country": "Country", + "deleteConfirmMessage": "Are you sure you want to delete '%{certificate}' issued by %{issuedBy}? This action cannot be undone.", + "duplicateAlternateName": "Duplicate alternate name", + "emailAddress": "Email address", + "generateACertificateSigningRequest": "Generate a Certificate Signing Request (CSR)", + "keyBitLength": "Key bit length", + "keyCurveId": "Key curve ID", + "keyPairAlgorithm": "Key pair algorithm", + "privateKey": "Private key", + "state": "State" }, "table": { "certificate": "Certificate", @@ -266,5 +288,256 @@ "successDeleteCertificate": "Successfully deleted %{certificate}.", "successReplaceCertificate": "Successfully replaced %{certificate}." } + }, + "countries": { + "AF":"Afghanistan", + "AL":"Albania", + "DZ":"Algeria", + "AS":"American Samoa", + "AD":"Andorra", + "AO":"Angola", + "AI":"Anguilla", + "AQ":"Antarctica", + "AG":"Antigua and Barbuda", + "AR":"Argentina", + "AM":"Armenia", + "AW":"Aruba", + "AU":"Australia", + "AT":"Austria", + "AZ":"Azerbaijan", + "BS":"Bahamas, The", + "BH":"Bahrain", + "BD":"Bangladesh", + "BB":"Barbados", + "BY":"Belarus", + "BE":"Belgium", + "BZ":"Belize", + "BJ":"Benin", + "BM":"Bermuda", + "BT":"Bhutan", + "BO":"Bolivia", + "BQ":"Bonaire, Sint Eustatius and Saba", + "BA":"Bosnia and Herzegovina ", + "BW":"Bostwana", + "BV":"Bouvet Island", + "BR":"Brazil", + "IO":"British Indian Ocean Territory", + "BN":"Brunei Darussalam ", + "BG":"Bulgaria", + "BF":"Burkina Faso", + "BI":"Burundi", + "CV":"Cabo Verde", + "KH":"Cambodia", + "CM":"Cameroon", + "CA":"Canada", + "KY":"Cayman Islands", + "CF":"Central African Republic", + "TD":"Chad", + "CL":"Chile", + "CN":"China", + "CX":"Christmas Island ", + "CC":"Cocos(Keeling) Islands", + "CO":"Columbia", + "KM":"Comoros", + "CD":"Congo, The Democratic Republic of the", + "CG":"Congo", + "CK":"Cook Islands", + "CR":"Costa Rica", + "HR":"Croatia", + "CU":"Cuba", + "CW":"Curaçao", + "CY":"Cyprus", + "CZ":"Czechia", + "CI":"Côte d\"Ivoire", + "DK":"Denmark", + "DJ":"Djibouti", + "DM":"Dominica", + "DO":"Dominican Republic", + "EC":"Ecuador", + "EG":"Egypt", + "SV":"El Salvador", + "GQ":"Equatorial Guinea ", + "ER":"Eritrea", + "EE":"Estonia", + "SZ":"Eswatini", + "ET":"Ethiopia", + "FK":"Falkland Islands (Malvinas)", + "FO":"Faroe Islands", + "FJ":"Fiji", + "FI":"Finland", + "FR":"France", + "GF":"French Guiana", + "PF":"French Polynesia", + "TF":"French Southern Territories", + "GA":"Gabon", + "GM":"Gambia, The", + "GE":"Georgia", + "DE":"Germany", + "GH":"Ghana", + "GI":"Gibraltar", + "GR":"Greece", + "GL":"Greenland", + "GD":"Grenada", + "GP":"Guadeloupe", + "GU":"Guam", + "GT":"Guatemala", + "GG":"Guernsey", + "GN":"Guinea", + "GW":"Guinea-Bissau", + "GY":"Guyana", + "HT":"Haiti", + "HM":"Heard Island and McDonald Islands", + "VA":"Holy See", + "HN":"Honduras", + "HK":"Hong Kong", + "HU":"Hungary", + "IS":"Iceland", + "IN":"India", + "ID":"Indonesia", + "IR":"Iran, Islamic Republic of", + "IQ":"Iraq", + "IE":"Ireland", + "IM":"Isle of Man", + "IL":"Israel", + "IT":"Italy", + "JM":"Jamaica", + "JP":"Japan", + "JE":"Jersey", + "JO":"Jordan", + "KZ":"Kazakhstan", + "KE":"Kenya", + "KI":"Kiribati", + "KR":"Korea, Republic of", + "KP":"Korea, Democratic People\"s Republic of", + "KW":"Kuwait", + "KG":"Kyrgyzstan", + "LA":"Lao People\"s Democratic Republic", + "LV":"Latvia", + "LB":"Lebanon", + "LS":"Lesotho", + "LR":"Liberia", + "LY":"Libya", + "LI":"Liechtenstein", + "LT":"Lithuania", + "LU":"Luxembourg", + "MO":"Macao", + "MK":"Macedonia, The Former Yugoslav Republic of", + "MG":"Madagascar", + "MW":"Malawi", + "MY":"Malaysia", + "MV":"Maldives", + "ML":"Mali", + "MT":"Malta", + "MH":"Marshall Islands", + "MQ":"Martinique", + "MR":"Mauritania", + "MU":"Mauritius", + "YT":"Mayotte", + "MX":"Mexico", + "FM":"Micronesia, Federated States of", + "MD":"Moldova, Republic of", + "MC":"Monaco", + "MN":"Mongolia", + "ME":"Montenegro", + "MS":"Montserrat", + "MA":"Morocco", + "MZ":"Mozambique", + "MM":"Myanmar", + "NA":"Namibia", + "NR":"Nauru", + "NP":"Nepal", + "NL":"Netherlands", + "NC":"New Caledonia", + "NZ":"New Zealand", + "NI":"Nicaragua", + "NE":"Niger", + "NG":"Nigeria", + "NU":"Niue", + "NF":"Norfolk Island", + "MP":"Northern Mariana Islands", + "NO":"Norway", + "OM":"Oman", + "PK":"Pakistan", + "PW":"Palau", + "PS":"Palestine", + "PA":"Panama", + "PG":"Papua New Guinea", + "PY":"Paraguay", + "PE":"Peru", + "PH":"Philippines", + "PN":"Pitcairn", + "PL":"Poland", + "PT":"Portugal", + "PR":"Puerto Rico", + "QA":"Qatar", + "RO":"Romania", + "RU":"Russian Federation", + "RW":"Rwanda", + "RE":"Réunion", + "BL":"Saint Barthélemy", + "SH":"Saint Helena, Ascension and Tristan da Cunha", + "KN":"Saint Kitts and Nevis ", + "LC":"Saint Lucia", + "MF":"Saint Martin", + "PM":"Saint Pierre and Miquelon", + "VC":"Saint Vincent and the Grenadines", + "WS":"Samoa", + "SM":"San Marino ", + "ST":"Sao Tome and Principe", + "SA":"Saudi Arabia", + "SN":"Senegal", + "RS":"Serbia", + "SC":"Seychelles", + "SL":"Sierra Leone", + "SG":"Singapore", + "SX":"Sint Maarten", + "SK":"Slovakia", + "SI":"Slovenia", + "SB":"Solomon Islands", + "SO":"Somalia", + "ZA":"South Africa ", + "GS":"South Georgia and the South Sandwich Islands", + "SS":"South Sudan", + "ES":"Spain", + "LK":"Sri Lanka", + "SD":"Sudan", + "SR":"Suriname", + "SJ":"Svalbard and Jan Mayen", + "SE":"Sweden", + "CH":"Switzerland", + "SY":"Syrian Arab Republic", + "TW":"Taiwan", + "TJ":"Tajikistan", + "TZ":"Tanzania, United Republic of", + "TH":"Thailand", + "TL":"Timor-Leste", + "TG":"Togo", + "TK":"Tokelau", + "TO":"Tonga", + "TT":"Trinidad and Tobago", + "TN":"Tunisia", + "TR":"Turkey", + "TM":"Turkmenistan", + "TC":"Turks and Caicos Islands", + "TV":"Tuvalu", + "UG":"Uganda", + "UA":"Ukraine", + "AE":"United Arab Emirates", + "GB":"United Kingdom", + "UM":"United States Minor Outlying Islands", + "US":"United States of America", + "UY":"Uruguay", + "UZ":"Uzbekistan", + "VU":"Vanuatu", + "VE":"Venezuela", + "VN":"Viet Nam", + "VG":"Virgin Islands, British", + "VI":"Virgin Islands, U.S", + "WF":"Wallis and Futuna", + "EH":"Western Sahara", + "YE":"Yemen", + "ZM":"Zambia", + "ZW":"Zimbabwe", + "AX": "Åland Islands" } }
\ No newline at end of file diff --git a/src/main.js b/src/main.js index 17fc50fa..7117c54d 100644 --- a/src/main.js +++ b/src/main.js @@ -15,6 +15,7 @@ import { FormInputPlugin, FormRadioPlugin, FormSelectPlugin, + FormTagsPlugin, LayoutPlugin, LinkPlugin, ListGroupPlugin, @@ -60,6 +61,10 @@ Vue.use(BVConfigPlugin, { BTable: { headVariant: 'light', footVariant: 'light' + }, + BFormTags: { + tagVariant: 'primary', + addButtonVariant: 'link-primary' } }); Vue.use(CollapsePlugin); @@ -70,6 +75,7 @@ Vue.use(FormGroupPlugin); Vue.use(FormInputPlugin); Vue.use(FormRadioPlugin); Vue.use(FormSelectPlugin); +Vue.use(FormTagsPlugin); Vue.use(LayoutPlugin); Vue.use(LayoutPlugin); Vue.use(LinkPlugin); diff --git a/src/store/modules/AccessControl/SslCertificatesStore.js b/src/store/modules/AccessControl/SslCertificatesStore.js index e1758d3c..ef4afdbb 100644 --- a/src/store/modules/AccessControl/SslCertificatesStore.js +++ b/src/store/modules/AccessControl/SslCertificatesStore.js @@ -1,7 +1,7 @@ import api from '../../api'; import i18n from '../../../i18n'; -const CERTIFICATE_TYPES = [ +export const CERTIFICATE_TYPES = [ { type: 'HTTPS Certificate', location: '/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/', @@ -151,6 +151,52 @@ const SslCertificatesStore = { i18n.t('pageSslCertificates.toast.errorDeleteCertificate') ); }); + }, + async generateCsr(_, userData) { + const { + certificateType, + country, + state, + city, + companyName, + companyUnit, + commonName, + keyPairAlgorithm, + keyBitLength, + keyCurveId, + challengePassword, + contactPerson, + emailAddress, + alternateName + } = userData; + const data = {}; + + data.CertificateCollection = { + '@odata.id': getCertificateProp(certificateType, 'location') + }; + data.Country = country; + data.State = state; + data.City = city; + data.Organization = companyName; + data.OrganizationalUnit = companyUnit; + data.CommonName = commonName; + data.KeyPairAlgorithm = keyPairAlgorithm; + data.AlternativeNames = alternateName; + + if (keyCurveId) data.KeyCurveId = keyCurveId; + if (keyBitLength) data.KeyBitLength = keyBitLength; + if (challengePassword) data.ChallengePassword = challengePassword; + if (contactPerson) data.ContactPerson = contactPerson; + if (emailAddress) data.Email = emailAddress; + + return await api + .post( + '/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR', + data + ) + //TODO: Success response also throws error so + // can't accurately show legitimate error in UI + .catch(error => console.log(error)); } } }; diff --git a/src/views/AccessControl/SslCertificates/CsrCountryCodes.js b/src/views/AccessControl/SslCertificates/CsrCountryCodes.js new file mode 100644 index 00000000..715fdfab --- /dev/null +++ b/src/views/AccessControl/SslCertificates/CsrCountryCodes.js @@ -0,0 +1,345 @@ +import i18n from '../../../i18n'; + +export const COUNTRY_LIST = [ + { name: 'Afghanistan', code: 'AF', label: i18n.t('countries.AF') }, + { name: 'Albania', code: 'AL', label: i18n.t('countries.AL') }, + { name: 'Algeria', code: 'DZ', label: i18n.t('countries.DZ') }, + { name: 'American Samoa', code: 'AS', label: i18n.t('countries.AS') }, + { name: 'Andorra', code: 'AD', label: i18n.t('countries.AD') }, + { name: 'Angola', code: 'AO', label: i18n.t('countries.AO') }, + { name: 'Anguilla', code: 'AI', label: i18n.t('countries.AI') }, + { name: 'Antarctica', code: 'AQ', label: i18n.t('countries.AQ') }, + { name: 'Antigua and Barbuda', code: 'AG', label: i18n.t('countries.AG') }, + { name: 'Argentina', code: 'AR', label: i18n.t('countries.AR') }, + { name: 'Armenia', code: 'AM', label: i18n.t('countries.AM') }, + { name: 'Aruba', code: 'AW', label: i18n.t('countries.AW') }, + { name: 'Australia', code: 'AU', label: i18n.t('countries.AU') }, + { name: 'Austria', code: 'AT', label: i18n.t('countries.AT') }, + { name: 'Azerbaijan', code: 'AZ', label: i18n.t('countries.AZ') }, + { name: 'Bahamas, The', code: 'BS', label: i18n.t('countries.BS') }, + { name: 'Bahrain', code: 'BH', label: i18n.t('countries.BH') }, + { name: 'Bangladesh', code: 'BD', label: i18n.t('countries.BD') }, + { name: 'Barbados', code: 'BB', label: i18n.t('countries.BB') }, + { name: 'Belarus', code: 'BY', label: i18n.t('countries.BY') }, + { name: 'Belgium', code: 'BE', label: i18n.t('countries.BE') }, + { name: 'Belize', code: 'BZ', label: i18n.t('countries.BZ') }, + { name: 'Benin', code: 'BJ', label: i18n.t('countries.BJ') }, + { name: 'Bermuda', code: 'BM', label: i18n.t('countries.BM') }, + { name: 'Bhutan', code: 'BT', label: i18n.t('countries.BT') }, + { name: 'Bolivia', code: 'BO', label: i18n.t('countries.BO') }, + { + name: 'Bonaire, Sint Eustatius and Saba', + code: 'BQ', + label: i18n.t('countries.BQ') + }, + { + name: 'Bosnia and Herzegovina ', + code: 'BA', + label: i18n.t('countries.BA') + }, + { name: 'Bostwana', code: 'BW', label: i18n.t('countries.BW') }, + { name: 'Bouvet Island', code: 'BV', label: i18n.t('countries.BV') }, + { name: 'Brazil', code: 'BR', label: i18n.t('countries.BR') }, + { + name: 'British Indian Ocean Territory', + code: 'IO', + label: i18n.t('countries.IO') + }, + { name: 'Brunei Darussalam ', code: 'BN', label: i18n.t('countries.BN') }, + { name: 'Bulgaria', code: 'BG', label: i18n.t('countries.BG') }, + { name: 'Burkina Faso', code: 'BF', label: i18n.t('countries.BF') }, + { name: 'Burundi', code: 'BI', label: i18n.t('countries.BI') }, + { name: 'Cabo Verde', code: 'CV', label: i18n.t('countries.CV') }, + { name: 'Cambodia', code: 'KH', label: i18n.t('countries.KH') }, + { name: 'Cameroon', code: 'CM', label: i18n.t('countries.CM') }, + { name: 'Canada', code: 'CA', label: i18n.t('countries.CA') }, + { name: 'Cayman Islands', code: 'KY', label: i18n.t('countries.KY') }, + { + name: 'Central African Republic', + code: 'CF', + label: i18n.t('countries.CF') + }, + { name: 'Chad', code: 'TD', label: i18n.t('countries.TD') }, + { name: 'Chile', code: 'CL', label: i18n.t('countries.CL') }, + { name: 'China', code: 'CN', label: i18n.t('countries.CN') }, + { name: 'Christmas Island ', code: 'CX', label: i18n.t('countries.CX') }, + { name: 'Cocos(Keeling) Islands', code: 'CC', label: i18n.t('countries.CC') }, + { name: 'Columbia', code: 'CO', label: i18n.t('countries.CO') }, + { name: 'Comoros', code: 'KM', label: i18n.t('countries.KM') }, + { + name: 'Congo, The Democratic Republic of the', + code: 'CD', + label: i18n.t('countries.CD') + }, + { name: 'Congo', code: 'CG', label: i18n.t('countries.CG') }, + { name: 'Cook Islands', code: 'CK', label: i18n.t('countries.CK') }, + { name: 'Costa Rica', code: 'CR', label: i18n.t('countries.CR') }, + { name: 'Croatia', code: 'HR', label: i18n.t('countries.HR') }, + { name: 'Cuba', code: 'CU', label: i18n.t('countries.CU') }, + { name: 'Curaçao', code: 'CW', label: i18n.t('countries.CW') }, + { name: 'Cyprus', code: 'CY', label: i18n.t('countries.CY') }, + { name: 'Czechia', code: 'CZ', label: i18n.t('countries.CZ') }, + { name: "Côte d'Ivoire", code: 'CI', label: i18n.t('countries.CI') }, + { name: 'Denmark', code: 'DK', label: i18n.t('countries.DK') }, + { name: 'Djibouti', code: 'DJ', label: i18n.t('countries.DJ') }, + { name: 'Dominica', code: 'DM', label: i18n.t('countries.DM') }, + { name: 'Dominican Republic', code: 'DO', label: i18n.t('countries.DO') }, + { name: 'Ecuador', code: 'EC', label: i18n.t('countries.EC') }, + { name: 'Egypt', code: 'EG', label: i18n.t('countries.EG') }, + { name: 'El Salvador', code: 'SV', label: i18n.t('countries.SV') }, + { name: 'Equatorial Guinea ', code: 'GQ', label: i18n.t('countries.GQ') }, + { name: 'Eritrea', code: 'ER', label: i18n.t('countries.ER') }, + { name: 'Estonia', code: 'EE', label: i18n.t('countries.EE') }, + { name: 'Eswatini', code: 'SZ', label: i18n.t('countries.SZ') }, + { name: 'Ethiopia', code: 'ET', label: i18n.t('countries.ET') }, + { + name: 'Falkland Islands (Malvinas)', + code: 'FK', + label: i18n.t('countries.FK') + }, + { name: 'Faroe Islands', code: 'FO', label: i18n.t('countries.FO') }, + { name: 'Fiji', code: 'FJ', label: i18n.t('countries.FJ') }, + { name: 'Finland', code: 'FI', label: i18n.t('countries.FI') }, + { name: 'France', code: 'FR', label: i18n.t('countries.FR') }, + { name: 'French Guiana', code: 'GF', label: i18n.t('countries.GF') }, + { name: 'French Polynesia', code: 'PF', label: i18n.t('countries.PF') }, + { + name: 'French Southern Territories', + code: 'TF', + label: i18n.t('countries.TF') + }, + { name: 'Gabon', code: 'GA', label: i18n.t('countries.GA') }, + { name: 'Gambia, The', code: 'GM', label: i18n.t('countries.GM') }, + { name: 'Georgia', code: 'GE', label: i18n.t('countries.GE') }, + { name: 'Germany', code: 'DE', label: i18n.t('countries.DE') }, + { name: 'Ghana', code: 'GH', label: i18n.t('countries.GH') }, + { name: 'Gibraltar', code: 'GI', label: i18n.t('countries.GI') }, + { name: 'Greece', code: 'GR', label: i18n.t('countries.GR') }, + { name: 'Greenland', code: 'GL', label: i18n.t('countries.GL') }, + { name: 'Grenada', code: 'GD', label: i18n.t('countries.GD') }, + { name: 'Guadeloupe', code: 'GP', label: i18n.t('countries.GP') }, + { name: 'Guam', code: 'GU', label: i18n.t('countries.GU') }, + { name: 'Guatemala', code: 'GT', label: i18n.t('countries.GT') }, + { name: 'Guernsey', code: 'GG', label: i18n.t('countries.GG') }, + { name: 'Guinea', code: 'GN', label: i18n.t('countries.GN') }, + { name: 'Guinea-Bissau', code: 'GW', label: i18n.t('countries.GW') }, + { name: 'Guyana', code: 'GY', label: i18n.t('countries.GY') }, + { name: 'Haiti', code: 'HT', label: i18n.t('countries.HT') }, + { + name: 'Heard Island and McDonald Islands', + code: 'HM', + label: i18n.t('countries.HM') + }, + { name: 'Holy See', code: 'VA', label: i18n.t('countries.VA') }, + { name: 'Honduras', code: 'HN', label: i18n.t('countries.HN') }, + { name: 'Hong Kong', code: 'HK', label: i18n.t('countries.HK') }, + { name: 'Hungary', code: 'HU', label: i18n.t('countries.HU') }, + { name: 'Iceland', code: 'IS', label: i18n.t('countries.IS') }, + { name: 'India', code: 'IN', label: i18n.t('countries.IN') }, + { name: 'Indonesia', code: 'ID', label: i18n.t('countries.ID') }, + { + name: 'Iran, Islamic Republic of', + code: 'IR', + label: i18n.t('countries.IR') + }, + { name: 'Iraq', code: 'IQ', label: i18n.t('countries.IQ') }, + { name: 'Ireland', code: 'IE', label: i18n.t('countries.IE') }, + { name: 'Isle of Man', code: 'IM', label: i18n.t('countries.IM') }, + { name: 'Israel', code: 'IL', label: i18n.t('countries.IL') }, + { name: 'Italy', code: 'IT', label: i18n.t('countries.IT') }, + { name: 'Jamaica', code: 'JM', label: i18n.t('countries.JM') }, + { name: 'Japan', code: 'JP', label: i18n.t('countries.JP') }, + { name: 'Jersey', code: 'JE', label: i18n.t('countries.JE') }, + { name: 'Jordan', code: 'JO', label: i18n.t('countries.JO') }, + { name: 'Kazakhstan', code: 'KZ', label: i18n.t('countries.KZ') }, + { name: 'Kenya', code: 'KE', label: i18n.t('countries.KE') }, + { name: 'Kiribati', code: 'KI', label: i18n.t('countries.KI') }, + { name: 'Korea, Republic of', code: 'KR', label: i18n.t('countries.KR') }, + { + name: "Korea, Democratic People's Republic of", + code: 'KP', + label: i18n.t('countries.KP') + }, + { name: 'Kuwait', code: 'KW', label: i18n.t('countries.KW') }, + { name: 'Kyrgyzstan', code: 'KG', label: i18n.t('countries.KG') }, + { + name: "Lao People's Democratic Republic", + code: 'LA', + label: i18n.t('countries.LA') + }, + { name: 'Latvia', code: 'LV', label: i18n.t('countries.LV') }, + { name: 'Lebanon', code: 'LB', label: i18n.t('countries.LB') }, + { name: 'Lesotho', code: 'LS', label: i18n.t('countries.LS') }, + { name: 'Liberia', code: 'LR', label: i18n.t('countries.LR') }, + { name: 'Libya', code: 'LY', label: i18n.t('countries.LY') }, + { name: 'Liechtenstein', code: 'LI', label: i18n.t('countries.LI') }, + { name: 'Lithuania', code: 'LT', label: i18n.t('countries.LT') }, + { name: 'Luxembourg', code: 'LU', label: i18n.t('countries.LU') }, + { name: 'Macao', code: 'MO', label: i18n.t('countries.MO') }, + { + name: 'Macedonia, The Former Yugoslav Republic of', + code: 'MK', + label: i18n.t('countries.MK') + }, + { name: 'Madagascar', code: 'MG', label: i18n.t('countries.MG') }, + { name: 'Malawi', code: 'MW', label: i18n.t('countries.MW') }, + { name: 'Malaysia', code: 'MY', label: i18n.t('countries.MY') }, + { name: 'Maldives', code: 'MV', label: i18n.t('countries.MV') }, + { name: 'Mali', code: 'ML', label: i18n.t('countries.ML') }, + { name: 'Malta', code: 'MT', label: i18n.t('countries.MT') }, + { name: 'Marshall Islands', code: 'MH', label: i18n.t('countries.MH') }, + { name: 'Martinique', code: 'MQ', label: i18n.t('countries.MQ') }, + { name: 'Mauritania', code: 'MR', label: i18n.t('countries.MR') }, + { name: 'Mauritius', code: 'MU', label: i18n.t('countries.MU') }, + { name: 'Mayotte', code: 'YT', label: i18n.t('countries.YT') }, + { name: 'Mexico', code: 'MX', label: i18n.t('countries.MX') }, + { + name: 'Micronesia, Federated States of', + code: 'FM', + label: i18n.t('countries.FM') + }, + { name: 'Moldova, Republic of', code: 'MD', label: i18n.t('countries.MD') }, + { name: 'Monaco', code: 'MC', label: i18n.t('countries.MC') }, + { name: 'Mongolia', code: 'MN', label: i18n.t('countries.MN') }, + { name: 'Montenegro', code: 'ME', label: i18n.t('countries.ME') }, + { name: 'Montserrat', code: 'MS', label: i18n.t('countries.MS') }, + { name: 'Morocco', code: 'MA', label: i18n.t('countries.MA') }, + { name: 'Mozambique', code: 'MZ', label: i18n.t('countries.MZ') }, + { name: 'Myanmar', code: 'MM', label: i18n.t('countries.MM') }, + { name: 'Namibia', code: 'NA', label: i18n.t('countries.NA') }, + { name: 'Nauru', code: 'NR', label: i18n.t('countries.NR') }, + { name: 'Nepal', code: 'NP', label: i18n.t('countries.NP') }, + { name: 'Netherlands', code: 'NL', label: i18n.t('countries.NL') }, + { name: 'New Caledonia', code: 'NC', label: i18n.t('countries.NC') }, + { name: 'New Zealand', code: 'NZ', label: i18n.t('countries.NZ') }, + { name: 'Nicaragua', code: 'NI', label: i18n.t('countries.NI') }, + { name: 'Niger', code: 'NE', label: i18n.t('countries.NE') }, + { name: 'Nigeria', code: 'NG', label: i18n.t('countries.NG') }, + { name: 'Niue', code: 'NU', label: i18n.t('countries.NU') }, + { name: 'Norfolk Island', code: 'NF', label: i18n.t('countries.NF') }, + { + name: 'Northern Mariana Islands', + code: 'MP', + label: i18n.t('countries.MP') + }, + { name: 'Norway', code: 'NO', label: i18n.t('countries.NO') }, + { name: 'Oman', code: 'OM', label: i18n.t('countries.OM') }, + { name: 'Pakistan', code: 'PK', label: i18n.t('countries.PK') }, + { name: 'Palau', code: 'PW', label: i18n.t('countries.PW') }, + { name: 'Palestine', code: 'PS', label: i18n.t('countries.PS') }, + { name: 'Panama', code: 'PA', label: i18n.t('countries.PA') }, + { name: 'Papua New Guinea', code: 'PG', label: i18n.t('countries.PG') }, + { name: 'Paraguay', code: 'PY', label: i18n.t('countries.PY') }, + { name: 'Peru', code: 'PE', label: i18n.t('countries.PE') }, + { name: 'Philippines', code: 'PH', label: i18n.t('countries.PH') }, + { name: 'Pitcairn', code: 'PN', label: i18n.t('countries.PN') }, + { name: 'Poland', code: 'PL', label: i18n.t('countries.PL') }, + { name: 'Portugal', code: 'PT', label: i18n.t('countries.PT') }, + { name: 'Puerto Rico', code: 'PR', label: i18n.t('countries.PR') }, + { name: 'Qatar', code: 'QA', label: i18n.t('countries.QA') }, + { name: 'Romania', code: 'RO', label: i18n.t('countries.RO') }, + { name: 'Russian Federation', code: 'RU', label: i18n.t('countries.RU') }, + { name: 'Rwanda', code: 'RW', label: i18n.t('countries.RW') }, + { name: 'Réunion', code: 'RE', label: i18n.t('countries.RE') }, + { name: 'Saint Barthélemy', code: 'BL', label: i18n.t('countries.BL') }, + { + name: 'Saint Helena, Ascension and Tristan da Cunha', + code: 'SH', + label: i18n.t('countries.SH') + }, + { name: 'Saint Kitts and Nevis ', code: 'KN', label: i18n.t('countries.KN') }, + { name: 'Saint Lucia', code: 'LC', label: i18n.t('countries.LC') }, + { name: 'Saint Martin', code: 'MF', label: i18n.t('countries.MF') }, + { + name: 'Saint Pierre and Miquelon', + code: 'PM', + label: i18n.t('countries.PM') + }, + { + name: 'Saint Vincent and the Grenadines', + code: 'VC', + label: i18n.t('countries.VC') + }, + { name: 'Samoa', code: 'WS', label: i18n.t('countries.WS') }, + { name: 'San Marino ', code: 'SM', label: i18n.t('countries.SM') }, + { name: 'Sao Tome and Principe', code: 'ST', label: i18n.t('countries.ST') }, + { name: 'Saudi Arabia', code: 'SA', label: i18n.t('countries.SA') }, + { name: 'Senegal', code: 'SN', label: i18n.t('countries.SN') }, + { name: 'Serbia', code: 'RS', label: i18n.t('countries.RS') }, + { name: 'Seychelles', code: 'SC', label: i18n.t('countries.SC') }, + { name: 'Sierra Leone', code: 'SL', label: i18n.t('countries.SL') }, + { name: 'Singapore', code: 'SG', label: i18n.t('countries.SG') }, + { name: 'Sint Maarten', code: 'SX', label: i18n.t('countries.SX') }, + { name: 'Slovakia', code: 'SK', label: i18n.t('countries.SK') }, + { name: 'Slovenia', code: 'SI', label: i18n.t('countries.SI') }, + { name: 'Solomon Islands', code: 'SB', label: i18n.t('countries.SB') }, + { name: 'Somalia', code: 'SO', label: i18n.t('countries.SO') }, + { name: 'South Africa ', code: 'ZA', label: i18n.t('countries.ZA') }, + { + name: 'South Georgia and the South Sandwich Islands', + code: 'GS', + label: i18n.t('countries.GS') + }, + { name: 'South Sudan', code: 'SS', label: i18n.t('countries.SS') }, + { name: 'Spain', code: 'ES', label: i18n.t('countries.ES') }, + { name: 'Sri Lanka', code: 'LK', label: i18n.t('countries.LK') }, + { name: 'Sudan', code: 'SD', label: i18n.t('countries.SD') }, + { name: 'Suriname', code: 'SR', label: i18n.t('countries.SR') }, + { name: 'Svalbard and Jan Mayen', code: 'SJ', label: i18n.t('countries.SJ') }, + { name: 'Sweden', code: 'SE', label: i18n.t('countries.SE') }, + { name: 'Switzerland', code: 'CH', label: i18n.t('countries.CH') }, + { name: 'Syrian Arab Republic', code: 'SY', label: i18n.t('countries.SY') }, + { name: 'Taiwan', code: 'TW', label: i18n.t('countries.TW') }, + { name: 'Tajikistan', code: 'TJ', label: i18n.t('countries.TJ') }, + { + name: 'Tanzania, United Republic of', + code: 'TZ', + label: i18n.t('countries.TZ') + }, + { name: 'Thailand', code: 'TH', label: i18n.t('countries.TH') }, + { name: 'Timor-Leste', code: 'TL', label: i18n.t('countries.TL') }, + { name: 'Togo', code: 'TG', label: i18n.t('countries.TG') }, + { name: 'Tokelau', code: 'TK', label: i18n.t('countries.TK') }, + { name: 'Tonga', code: 'TO', label: i18n.t('countries.TO') }, + { name: 'Trinidad and Tobago', code: 'TT', label: i18n.t('countries.TT') }, + { name: 'Tunisia', code: 'TN', label: i18n.t('countries.TN') }, + { name: 'Turkey', code: 'TR', label: i18n.t('countries.TR') }, + { name: 'Turkmenistan', code: 'TM', label: i18n.t('countries.TM') }, + { + name: 'Turks and Caicos Islands', + code: 'TC', + label: i18n.t('countries.TC') + }, + { name: 'Tuvalu', code: 'TV', label: i18n.t('countries.TV') }, + { name: 'Uganda', code: 'UG', label: i18n.t('countries.UG') }, + { name: 'Ukraine', code: 'UA', label: i18n.t('countries.UA') }, + { name: 'United Arab Emirates', code: 'AE', label: i18n.t('countries.AE') }, + { name: 'United Kingdom', code: 'GB', label: i18n.t('countries.GB') }, + { + name: 'United States Minor Outlying Islands', + code: 'UM', + label: i18n.t('countries.UM') + }, + { + name: 'United States of America', + code: 'US', + label: i18n.t('countries.US') + }, + { name: 'Uruguay', code: 'UY', label: i18n.t('countries.UY') }, + { name: 'Uzbekistan', code: 'UZ', label: i18n.t('countries.UZ') }, + { name: 'Vanuatu', code: 'VU', label: i18n.t('countries.VU') }, + { name: 'Venezuela', code: 'VE', label: i18n.t('countries.VE') }, + { name: 'Viet Nam', code: 'VN', label: i18n.t('countries.VN') }, + { + name: 'Virgin Islands, British', + code: 'VG', + label: i18n.t('countries.VG') + }, + { name: 'Virgin Islands, U.S', code: 'VI', label: i18n.t('countries.VI') }, + { name: 'Wallis and Futuna', code: 'WF', label: i18n.t('countries.WF') }, + { name: 'Western Sahara', code: 'EH', label: i18n.t('countries.EH') }, + { name: 'Yemen', code: 'YE', label: i18n.t('countries.YE') }, + { name: 'Zambia', code: 'ZM', label: i18n.t('countries.ZM') }, + { name: 'Zimbabwe', code: 'ZW', label: i18n.t('countries.ZW') }, + { name: 'Åland Islands', code: 'AX', label: i18n.t('countries.AX') } +]; diff --git a/src/views/AccessControl/SslCertificates/ModalGenerateCsr.vue b/src/views/AccessControl/SslCertificates/ModalGenerateCsr.vue new file mode 100644 index 00000000..3f53c41b --- /dev/null +++ b/src/views/AccessControl/SslCertificates/ModalGenerateCsr.vue @@ -0,0 +1,479 @@ +<template> + <div> + <b-modal + id="generate-csr" + ref="modal" + size="lg" + no-stacking + :title=" + $t('pageSslCertificates.modal.generateACertificateSigningRequest') + " + @ok="onOkGenerateCsrModal" + @cancel="resetForm" + @hidden="$v.$reset()" + > + <b-form id="generate-csr-form" novalidate @submit="handleSubmit"> + <b-container fluid> + <b-row> + <b-col lg="9"> + <b-row> + <b-col lg="6"> + <b-form-group + :label=" + $t('pageSslCertificates.modal.certificateType') + ' *' + " + label-for="certificate-type" + > + <b-form-select + id="certificate-type" + v-model="form.certificateType" + :options="certificateOptions" + :state="getValidationState($v.form.certificateType)" + @input="$v.form.certificateType.$touch()" + > + <template v-slot:first> + <b-form-select-option :value="null" disabled> + {{ $t('global.form.selectAnOption') }} + </b-form-select-option> + </template> + </b-form-select> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.fieldRequired') }} + </b-form-invalid-feedback> + </b-form-group> + </b-col> + <b-col lg="6"> + <b-form-group + :label="$t('pageSslCertificates.modal.country') + ' *'" + label-for="country" + > + <b-form-select + id="country" + v-model="form.country" + :options="countryOptions" + :state="getValidationState($v.form.country)" + @input="$v.form.country.$touch()" + > + <template v-slot:first> + <b-form-select-option :value="null" disabled> + {{ $t('global.form.selectAnOption') }} + </b-form-select-option> + </template> + </b-form-select> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.fieldRequired') }} + </b-form-invalid-feedback> + </b-form-group> + </b-col> + </b-row> + <b-row> + <b-col lg="6"> + <b-form-group + :label="$t('pageSslCertificates.modal.state') + ' *'" + label-for="state" + > + <b-form-input + id="state" + v-model="form.state" + type="text" + :state="getValidationState($v.form.state)" + /> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.fieldRequired') }} + </b-form-invalid-feedback> + </b-form-group> + </b-col> + <b-col lg="6"> + <b-form-group + :label="$t('pageSslCertificates.modal.city') + ' *'" + label-for="city" + > + <b-form-input + id="city" + v-model="form.city" + type="text" + :state="getValidationState($v.form.city)" + /> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.fieldRequired') }} + </b-form-invalid-feedback> + </b-form-group> + </b-col> + </b-row> + <b-row> + <b-col lg="6"> + <b-form-group + :label="$t('pageSslCertificates.modal.companyName') + ' *'" + label-for="company-name" + > + <b-form-input + id="company-name" + v-model="form.companyName" + type="text" + :state="getValidationState($v.form.companyName)" + /> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.fieldRequired') }} + </b-form-invalid-feedback> + </b-form-group> + </b-col> + <b-col lg="6"> + <b-form-group + :label="$t('pageSslCertificates.modal.companyUnit') + ' *'" + label-for="company-unit" + > + <b-form-input + id="company-unit" + v-model="form.companyUnit" + type="text" + :state="getValidationState($v.form.companyUnit)" + /> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.fieldRequired') }} + </b-form-invalid-feedback> + </b-form-group> + </b-col> + </b-row> + <b-row> + <b-col lg="6"> + <b-form-group + :label="$t('pageSslCertificates.modal.commonName') + ' *'" + label-for="common-name" + > + <b-form-input + id="common-name" + v-model="form.commonName" + type="text" + :state="getValidationState($v.form.commonName)" + /> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.fieldRequired') }} + </b-form-invalid-feedback> + </b-form-group> + </b-col> + <b-col lg="6"> + <b-form-group + :label="$t('pageSslCertificates.modal.challengePassword')" + label-for="challenge-password" + > + <b-form-input + id="challenge-password" + v-model="form.challengePassword" + type="text" + /> + </b-form-group> + </b-col> + </b-row> + <b-row> + <b-col lg="6"> + <b-form-group + :label="$t('pageSslCertificates.modal.contactPerson')" + label-for="contact-person" + > + <b-form-input + id="contact-person" + v-model="form.contactPerson" + type="text" + /> + </b-form-group> + </b-col> + <b-col lg="6"> + <b-form-group + :label="$t('pageSslCertificates.modal.emailAddress')" + label-for="email-address" + > + <b-form-input + id="email-address" + v-model="form.emailAddress" + type="text" + /> + </b-form-group> + </b-col> + </b-row> + <b-row> + <b-col lg="12"> + <b-form-group + :label="$t('pageSslCertificates.modal.alternateName')" + label-for="alternate-name" + > + <b-form-text id="alternate-name-help-block"> + {{ + $t('pageSslCertificates.modal.alternateNameHelperText') + }} + </b-form-text> + <b-form-tags + v-model="form.alternateName" + :remove-on-delete="true" + :tag-pills="true" + input-id="alternate-name" + size="lg" + separator=" " + :input-attrs="{ + 'aria-describedby': 'alternate-name-help-block' + }" + :duplicate-tag-text=" + $t('pageSslCertificates.modal.duplicateAlternateName') + " + placeholder="" + > + <template v-slot:add-button-text> + {{ $t('global.action.add') }} <icon-add /> + </template> + </b-form-tags> + </b-form-group> + </b-col> + </b-row> + </b-col> + <b-col lg="3"> + <b-row> + <b-col lg="12"> + <p class="col-form-label"> + {{ $t('pageSslCertificates.modal.privateKey') }} + </p> + <b-form-group + :label=" + $t('pageSslCertificates.modal.keyPairAlgorithm') + ' *' + " + label-for="key-pair-algorithm" + > + <b-form-select + id="key-pair-algorithm" + v-model="form.keyPairAlgorithm" + :options="keyPairAlgorithmOptions" + :state="getValidationState($v.form.keyPairAlgorithm)" + @input="$v.form.keyPairAlgorithm.$touch()" + > + <template v-slot:first> + <b-form-select-option :value="null" disabled> + {{ $t('global.form.selectAnOption') }} + </b-form-select-option> + </template> + </b-form-select> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.fieldRequired') }} + </b-form-invalid-feedback> + </b-form-group> + </b-col> + </b-row> + <b-row> + <b-col lg="12"> + <template v-if="$v.form.keyPairAlgorithm.$model === 'EC'"> + <b-form-group + :label="$t('pageSslCertificates.modal.keyCurveId') + ' *'" + label-for="key-curve-id" + > + <b-form-select + id="key-curve-id" + v-model="form.keyCurveId" + :options="keyCurveIdOptions" + :state="getValidationState($v.form.keyCurveId)" + @input="$v.form.keyCurveId.$touch()" + > + <template v-slot:first> + <b-form-select-option :value="null" disabled> + {{ $t('global.form.selectAnOption') }} + </b-form-select-option> + </template> + </b-form-select> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.fieldRequired') }} + </b-form-invalid-feedback> + </b-form-group> + </template> + <template v-if="$v.form.keyPairAlgorithm.$model === 'RSA'"> + <b-form-group + :label=" + $t('pageSslCertificates.modal.keyBitLength') + ' *' + " + label-for="key-bit-length" + > + <b-form-select + id="key-bit-length" + v-model="form.keyBitLength" + :options="keyBitLengthOptions" + :state="getValidationState($v.form.keyBitLength)" + @input="$v.form.keyBitLength.$touch()" + > + <template v-slot:first> + <b-form-select-option :value="null" disabled> + {{ $t('global.form.selectAnOption') }} + </b-form-select-option> + </template> + </b-form-select> + <b-form-invalid-feedback role="alert"> + {{ $t('global.form.fieldRequired') }} + </b-form-invalid-feedback> + </b-form-group> + </template> + </b-col> + </b-row> + </b-col> + </b-row> + </b-container> + </b-form> + <template v-slot:modal-footer="{ ok, cancel }"> + <b-button variant="secondary" @click="cancel()"> + {{ $t('global.action.cancel') }} + </b-button> + <b-button + form="generate-csr-form" + type="submit" + variant="primary" + @click="ok()" + > + {{ $t('pageSslCertificates.generateCsr') }} + </b-button> + </template> + </b-modal> + <b-modal + id="csr-string" + no-stacking + size="lg" + :title="$t('pageSslCertificates.modal.certificateSigningRequest')" + @hidden="onHiddenCsrStringModal" + > + {{ csrString }} + <template v-slot:modal-footer> + <b-btn variant="secondary" @click="copyCsrString"> + <template v-if="csrStringCopied"> + <icon-checkmark /> + {{ $t('global.status.copied') }} + </template> + <template v-else> + {{ $t('global.action.copy') }} + </template> + </b-btn> + <a + :href="`data:text/json;charset=utf-8,${csrString}`" + download="certificate.txt" + class="btn btn-primary" + > + {{ $t('global.action.download') }} + </a> + </template> + </b-modal> + </div> +</template> + +<script> +import IconAdd from '@carbon/icons-vue/es/add--alt/20'; +import IconCheckmark from '@carbon/icons-vue/es/checkmark/20'; + +import { required, requiredIf } from 'vuelidate/lib/validators'; + +import { COUNTRY_LIST } from './CsrCountryCodes'; +import { CERTIFICATE_TYPES } from '../../../store/modules/AccessControl/SslCertificatesStore'; +import BVToastMixin from '../../../components/Mixins/BVToastMixin'; +import VuelidateMixin from '../../../components/Mixins/VuelidateMixin.js'; + +export default { + name: 'ModalGenerateCsr', + components: { IconAdd, IconCheckmark }, + mixins: [BVToastMixin, VuelidateMixin], + data() { + return { + form: { + certificateType: null, + country: null, + state: null, + city: null, + companyName: null, + companyUnit: null, + commonName: null, + challengePassword: null, + contactPerson: null, + emailAddress: null, + alternateName: [], + keyPairAlgorithm: null, + keyCurveId: null, + keyBitLength: null + }, + certificateOptions: CERTIFICATE_TYPES.reduce((arr, cert) => { + if (cert.type === 'TrustStore Certificate') return arr; + arr.push({ + text: cert.label, + value: cert.type + }); + return arr; + }, []), + countryOptions: COUNTRY_LIST.map(country => ({ + text: country.label, + value: country.code + })), + keyPairAlgorithmOptions: ['EC', 'RSA'], + keyCurveIdOptions: ['prime256v1', 'secp521r1', 'secp384r1'], + keyBitLengthOptions: [2048], + csrString: '', + csrStringCopied: false + }; + }, + validations: { + form: { + certificateType: { required }, + country: { required }, + state: { required }, + city: { required }, + companyName: { required }, + companyUnit: { required }, + commonName: { required }, + challengePassword: {}, + contactPerson: {}, + emailAddress: {}, + alternateName: {}, + keyPairAlgorithm: { required }, + keyCurveId: { + reuired: requiredIf(function(form) { + return form.keyPairAlgorithm === 'EC'; + }) + }, + keyBitLength: { + reuired: requiredIf(function(form) { + return form.keyPairAlgorithm === 'RSA'; + }) + } + } + }, + methods: { + handleSubmit() { + this.$v.$touch(); + if (this.$v.$invalid) return; + this.$store + .dispatch('sslCertificates/generateCsr', this.form) + .then(({ data: { CSRString } }) => { + this.csrString = CSRString; + this.$bvModal.show('csr-string'); + this.$v.$reset(); + }); + }, + resetForm() { + for (let key of Object.keys(this.form)) { + if (key === 'alternateName') { + this.form[key] = []; + } else { + this.form[key] = null; + } + } + }, + onOkGenerateCsrModal(bvModalEvt) { + // prevent modal close + bvModalEvt.preventDefault(); + this.handleSubmit(); + }, + onHiddenCsrStringModal() { + this.csrString = ''; + this.resetForm(); + }, + copyCsrString(bvModalEvt) { + // prevent modal close + bvModalEvt.preventDefault(); + navigator.clipboard.writeText(this.csrString).then(() => { + // Show copied text for 5 seconds + this.csrStringCopied = true; + setTimeout(() => { + this.csrStringCopied = false; + }, 5000 /*5 seconds*/); + }); + } + } +}; +</script> diff --git a/src/views/AccessControl/SslCertificates/SslCertificates.vue b/src/views/AccessControl/SslCertificates/SslCertificates.vue index 313b3218..79cdea65 100644 --- a/src/views/AccessControl/SslCertificates/SslCertificates.vue +++ b/src/views/AccessControl/SslCertificates/SslCertificates.vue @@ -32,7 +32,11 @@ </b-col> </b-row> <b-row> - <b-col xl="9" class="text-right"> + <b-col xl="10" class="text-right"> + <b-button v-b-modal.generate-csr variant="link"> + <icon-add /> + {{ $t('pageSslCertificates.generateCsr') }} + </b-button> <b-button variant="primary" :disabled="certificatesForUpload.length === 0" @@ -44,7 +48,7 @@ </b-col> </b-row> <b-row> - <b-col xl="9"> + <b-col xl="10"> <b-table :fields="fields" :items="tableItems"> <template v-slot:cell(validFrom)="{ value }"> {{ value | formatDate }} @@ -79,6 +83,7 @@ <!-- Modals --> <modal-upload-certificate :certificate="modalCertificate" @ok="onModalOk" /> + <modal-generate-csr /> </b-container> </template> @@ -87,6 +92,7 @@ import IconAdd from '@carbon/icons-vue/es/add--alt/20'; import IconReplace from '@carbon/icons-vue/es/renew/20'; import IconTrashcan from '@carbon/icons-vue/es/trash-can/20'; +import ModalGenerateCsr from './ModalGenerateCsr'; import ModalUploadCertificate from './ModalUploadCertificate'; import PageTitle from '../../../components/Global/PageTitle'; import TableRowAction from '../../../components/Global/TableRowAction'; @@ -102,6 +108,7 @@ export default { IconAdd, IconReplace, IconTrashcan, + ModalGenerateCsr, ModalUploadCertificate, PageTitle, StatusIcon, |