diff --git a/src/views/portfolio/vulnerabilities/SelectAliasModal.vue b/src/views/portfolio/vulnerabilities/SelectAliasModal.vue new file mode 100644 index 000000000..483985c2e --- /dev/null +++ b/src/views/portfolio/vulnerabilities/SelectAliasModal.vue @@ -0,0 +1,88 @@ + + + diff --git a/src/views/portfolio/vulnerabilities/VulnerabilityCreateVulnerabilityModal.vue b/src/views/portfolio/vulnerabilities/VulnerabilityCreateVulnerabilityModal.vue index 5cfbc842d..7d0890641 100644 --- a/src/views/portfolio/vulnerabilities/VulnerabilityCreateVulnerabilityModal.vue +++ b/src/views/portfolio/vulnerabilities/VulnerabilityCreateVulnerabilityModal.vue @@ -77,6 +77,23 @@ /> + +
+ + + + +
+
@@ -893,6 +910,7 @@ }} + @@ -908,6 +926,7 @@ import { Switch as cSwitch } from '@coreui/vue'; import permissionsMixin from '../../../mixins/permissionsMixin'; import ActionableListGroupItem from '../../components/ActionableListGroupItem'; import SelectCweModal from './SelectCweModal'; +import SelectAliasModal from './SelectAliasModal'; import AddAffectedComponentModal from './AddAffectedComponentModal'; import VueEasyPieChart from 'vue-easy-pie-chart'; import { getStyle } from '@coreui/coreui/dist/js/coreui-utilities'; @@ -924,6 +943,7 @@ export default { BInputGroupFormInput, BInputGroupFormSelect, SelectCweModal, + SelectAliasModal, AddAffectedComponentModal, VueEasyPieChart, VueTagsInput, @@ -940,6 +960,7 @@ export default { currentCritical: 7.1, cvssv2Test: null, selectableCwes: [], + selectableAliases: [], vulnerability: { vulnId: null, // This has to be null on initial load so that the vulnId gets populated. source: 'INTERNAL', @@ -1483,6 +1504,20 @@ export default { this.vulnerability.vulnId = response.data; }); }, + resolveAliases: function (aliases) { + let aliasList = []; + if (aliases.length !== 0) { + let keys = Object.keys(aliases[0]); + for (let i = 0; i < keys.length; i++) { + let key = keys[i]; + if (key !== 'internalId' && aliases[0][key] !== null) { + aliasList.push(aliases[0][key]); + } + } + return aliasList; + } + return []; + }, createVulnerability: function () { let url = `${this.$api.BASE_URL}/${this.$api.URL_VULNERABILITY}`; this.axios @@ -1502,6 +1537,7 @@ export default { cvssV3Vector: this.generateCvssV3Vector(), owaspRRVector: this.generateOwaspRRVector(), cwes: this.selectableCwes, + aliases: this.selectableAliases, affectedComponents: this.vulnerability.affectedComponents, }) .then((response) => { @@ -1542,6 +1578,34 @@ export default { } } }, + updateAliasSelection: function (selections) { + this.$root.$emit('bv::hide::modal', 'selectAliasModal'); + let alias = this.vulnerability.aliases?.[0] ?? { + internalId: this.vulnerability.vulnId, + cveId: null, + ghsaId: null, + osvId: null, + }; + + selections.forEach((s) => { + if (s.source === 'NVD') alias.cveId = s.vulnId; + if (s.source === 'GITHUB') alias.ghsaId = s.vulnId; + if (s.source === 'OSV') alias.osvId = s.vulnId; + }); + + this.selectableAliases = [{ ...alias }]; + this.vulnerability.aliases = [{ ...alias }]; + }, + removeAlias: function (alias) { + if (!this.selectableAliases.length) return; + const oldAliases = this.selectableAliases[0]; + const newAliases = {}; + Object.keys(oldAliases).forEach((key) => { + newAliases[key] = oldAliases[key] === alias ? null : oldAliases[key]; + }); + this.selectableAliases = [newAliases]; + this.vulnerability.aliases = [newAliases]; + }, removeAffectedComponent: function (affectedComponent) { for (let i = 0; i < this.vulnerability.affectedComponents.length; i++) { let a = this.vulnerability.affectedComponents[i]; diff --git a/src/views/portfolio/vulnerabilities/VulnerabilityDetailsModal.vue b/src/views/portfolio/vulnerabilities/VulnerabilityDetailsModal.vue index b89670721..658066f7b 100644 --- a/src/views/portfolio/vulnerabilities/VulnerabilityDetailsModal.vue +++ b/src/views/portfolio/vulnerabilities/VulnerabilityDetailsModal.vue @@ -81,16 +81,17 @@
- +
@@ -954,6 +955,7 @@ >{{ $t('message.update') }} + 0) { this.selectableCwes = this.vulnerability.cwes; } + if ( + this.vulnerability.aliases && + Object.values(this.vulnerability.aliases).length > 0 + ) { + this.selectableAliases[0] = this.vulnerability.aliases[0]; + } } }, }, @@ -1745,6 +1755,7 @@ export default { cvssV3Vector: this.generateCvssV3Vector(), owaspRRVector: this.generateOwaspRRVector(), cwes: this.selectableCwes, + aliases: this.selectableAliases, affectedComponents: this.vulnerability.affectedComponents, }) .then((response) => { @@ -1773,6 +1784,50 @@ export default { this.$toastr.w(this.$t('condition.unsuccessful_action')); }); }, + resolveAliases: function (aliases) { + let aliasList = []; + if (aliases.length !== 0) { + let keys = Object.keys(aliases[0]); + for (let i = 0; i < keys.length; i++) { + let key = keys[i]; + if ( + key !== 'internalId' && + key !== 'uuid' && + aliases[0][key] !== null + ) { + aliasList.push(aliases[0][key]); + } + } + return aliasList; + } + return []; + }, + updateAliasSelection: function (selections) { + this.$root.$emit('bv::hide::modal', 'selectAliasModal'); + let alias = this.vulnerability.aliases?.[0] ?? { + internalId: this.vulnerability.vulnId, + cveId: null, + ghsaId: null, + osvId: null, + }; + selections.forEach((s) => { + if (s.source === 'NVD') alias.cveId = s.vulnId; + if (s.source === 'GITHUB') alias.ghsaId = s.vulnId; + if (s.source === 'OSV') alias.osvId = s.vulnId; + }); + this.selectableAliases = [{ ...alias }]; + this.vulnerability.aliases = [{ ...alias }]; + }, + removeAlias: function (alias) { + if (!this.selectableAliases.length) return; + const oldAliases = this.selectableAliases[0]; + const newAliases = {}; + Object.keys(oldAliases).forEach((key) => { + newAliases[key] = oldAliases[key] === alias ? null : oldAliases[key]; + }); + this.selectableAliases = [newAliases]; + this.vulnerability.aliases = [newAliases]; + }, updateCweSelection: function (selections) { this.$root.$emit('bv::hide::modal', 'selectCweModal'); for (let i = 0; i < selections.length; i++) {