1import api from '@/store/api'; 2import i18n from '@/i18n'; 3 4export const CERTIFICATE_TYPES = [ 5 { 6 type: 'HTTPS Certificate', 7 location: '/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/', 8 label: i18n.t('pageCertificates.httpsCertificate'), 9 }, 10 { 11 type: 'LDAP Certificate', 12 location: '/redfish/v1/AccountService/LDAP/Certificates/', 13 label: i18n.t('pageCertificates.ldapCertificate'), 14 }, 15 { 16 type: 'TrustStore Certificate', 17 location: '/redfish/v1/Managers/bmc/Truststore/Certificates/', 18 // Web UI will show 'CA Certificate' instead of 19 // 'TrustStore Certificate' after user testing revealed 20 // the term 'TrustStore Certificate' wasn't recognized/was unfamilar 21 label: i18n.t('pageCertificates.caCertificate'), 22 }, 23]; 24 25const getCertificateProp = (type, prop) => { 26 const certificate = CERTIFICATE_TYPES.find( 27 (certificate) => certificate.type === type 28 ); 29 return certificate ? certificate[prop] : null; 30}; 31 32const CertificatesStore = { 33 namespaced: true, 34 state: { 35 allCertificates: [], 36 availableUploadTypes: [], 37 }, 38 getters: { 39 allCertificates: (state) => state.allCertificates, 40 availableUploadTypes: (state) => state.availableUploadTypes, 41 }, 42 mutations: { 43 setCertificates(state, certificates) { 44 state.allCertificates = certificates; 45 }, 46 setAvailableUploadTypes(state, availableUploadTypes) { 47 state.availableUploadTypes = availableUploadTypes; 48 }, 49 }, 50 actions: { 51 async getCertificates({ commit }) { 52 return await api 53 .get('/redfish/v1/CertificateService/CertificateLocations') 54 .then(({ data: { Links: { Certificates } } }) => 55 Certificates.map((certificate) => certificate['@odata.id']) 56 ) 57 .then((certificateLocations) => { 58 const promises = certificateLocations.map((location) => 59 api.get(location) 60 ); 61 api.all(promises).then( 62 api.spread((...responses) => { 63 const certificates = responses.map(({ data }) => { 64 const { 65 Name, 66 ValidNotAfter, 67 ValidNotBefore, 68 Issuer = {}, 69 Subject = {}, 70 } = data; 71 return { 72 type: Name, 73 location: data['@odata.id'], 74 certificate: getCertificateProp(Name, 'label'), 75 issuedBy: Issuer.CommonName, 76 issuedTo: Subject.CommonName, 77 validFrom: new Date(ValidNotBefore), 78 validUntil: new Date(ValidNotAfter), 79 }; 80 }); 81 const availableUploadTypes = CERTIFICATE_TYPES.filter( 82 ({ type }) => 83 !certificates 84 .map((certificate) => certificate.type) 85 .includes(type) 86 ); 87 88 commit('setCertificates', certificates); 89 commit('setAvailableUploadTypes', availableUploadTypes); 90 }) 91 ); 92 }); 93 }, 94 async addNewCertificate({ dispatch }, { file, type }) { 95 return await api 96 .post(getCertificateProp(type, 'location'), file, { 97 headers: { 'Content-Type': 'application/x-pem-file' }, 98 }) 99 .then(() => dispatch('getCertificates')) 100 .then(() => 101 i18n.t('pageCertificates.toast.successAddCertificate', { 102 certificate: getCertificateProp(type, 'label'), 103 }) 104 ) 105 .catch((error) => { 106 console.log(error); 107 throw new Error(i18n.t('pageCertificates.toast.errorAddCertificate')); 108 }); 109 }, 110 async replaceCertificate( 111 { dispatch }, 112 { certificateString, location, type } 113 ) { 114 const data = {}; 115 data.CertificateString = certificateString; 116 data.CertificateType = 'PEM'; 117 data.CertificateUri = { '@odata.id': location }; 118 119 return await api 120 .post( 121 '/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate', 122 data 123 ) 124 .then(() => dispatch('getCertificates')) 125 .then(() => 126 i18n.t('pageCertificates.toast.successReplaceCertificate', { 127 certificate: getCertificateProp(type, 'label'), 128 }) 129 ) 130 .catch((error) => { 131 console.log(error); 132 throw new Error( 133 i18n.t('pageCertificates.toast.errorReplaceCertificate') 134 ); 135 }); 136 }, 137 async deleteCertificate({ dispatch }, { type, location }) { 138 return await api 139 .delete(location) 140 .then(() => dispatch('getCertificates')) 141 .then(() => 142 i18n.t('pageCertificates.toast.successDeleteCertificate', { 143 certificate: getCertificateProp(type, 'label'), 144 }) 145 ) 146 .catch((error) => { 147 console.log(error); 148 throw new Error( 149 i18n.t('pageCertificates.toast.errorDeleteCertificate') 150 ); 151 }); 152 }, 153 async generateCsr(_, userData) { 154 const { 155 certificateType, 156 country, 157 state, 158 city, 159 companyName, 160 companyUnit, 161 commonName, 162 keyPairAlgorithm, 163 keyBitLength, 164 keyCurveId, 165 challengePassword, 166 contactPerson, 167 emailAddress, 168 alternateName, 169 } = userData; 170 const data = {}; 171 172 data.CertificateCollection = { 173 '@odata.id': getCertificateProp(certificateType, 'location'), 174 }; 175 data.Country = country; 176 data.State = state; 177 data.City = city; 178 data.Organization = companyName; 179 data.OrganizationalUnit = companyUnit; 180 data.CommonName = commonName; 181 data.KeyPairAlgorithm = keyPairAlgorithm; 182 data.AlternativeNames = alternateName; 183 184 if (keyCurveId) data.KeyCurveId = keyCurveId; 185 if (keyBitLength) data.KeyBitLength = keyBitLength; 186 if (challengePassword) data.ChallengePassword = challengePassword; 187 if (contactPerson) data.ContactPerson = contactPerson; 188 if (emailAddress) data.Email = emailAddress; 189 190 return await api 191 .post( 192 '/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR', 193 data 194 ) 195 //TODO: Success response also throws error so 196 // can't accurately show legitimate error in UI 197 .catch((error) => console.log(error)); 198 }, 199 }, 200}; 201 202export default CertificatesStore; 203