Skip to content

Commit cf0ce89

Browse files
authored
Merge pull request #489 from nscuro/backport-to-4.8.1
Backport fixes to 4.8.1
2 parents e414ddf + 0fcecfc commit cf0ce89

File tree

8 files changed

+83
-55
lines changed

8 files changed

+83
-55
lines changed

src/shared/common.js

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ $common.formatNotificationLabel = function formatNotificationLabel(violationStat
3535
/**
3636
* Formats and returns a specialized label for a project tag.
3737
*/
38-
$common.formatProjectTagLabel = function formatProjectTagLabel(tag) {
38+
$common.formatProjectTagLabel = function formatProjectTagLabel(router, tag) {
3939
if (! tag) {
4040
return "";
4141
}
42-
return `<a href="../projects/?tag=${xssFilters.uriComponentInUnQuotedAttr(tag.name)}" class="badge badge-tag text-lowercase mr-1">${xssFilters.inHTMLData(tag.name)}</a>`
42+
return `<a href="${router.resolve({name: 'Projects', query: {'tag': tag.name}}).href}" class="badge badge-tag text-lowercase mr-1">${xssFilters.inHTMLData(tag.name)}</a>`
4343
};
4444

4545
/**
@@ -191,32 +191,55 @@ $common.resolveSourceVulnInfo = function resolveSourceVulnInfo(vulnSource, vulnI
191191
return sourceInfo;
192192
}
193193

194-
/**
195-
* Given the source of a vulnerability (vulnSource) and an alias of the vulnerability, normalizes
196-
* the return object.
197-
* @param vulnSource the source of a Vulnerability object
198-
* @param alias a VulnerabilityAlias response object for the given Vulnerability
199-
* @returns A resolved and normalized object with metadata
200-
*/
201-
$common.resolveVulnAliasInfo = function resolveVulnAliasInfo(vulnSource, alias) {
202-
if (!vulnSource || !alias) return;
203-
if (vulnSource !== "INTERNAL" && alias.internalId) {
204-
return $common.resolveSourceVulnInfo("INTERNAL", alias.internalId);
205-
} else if (vulnSource !== "NVD" && alias.cveId) {
206-
return $common.resolveSourceVulnInfo("NVD", alias.cveId);
207-
} else if (vulnSource !== "GITHUB" && alias.ghsaId) {
208-
return $common.resolveSourceVulnInfo("GITHUB", alias.ghsaId);
209-
} else if (vulnSource !== "OSSINDEX" && alias.sonatypeId) {
210-
return $common.resolveSourceVulnInfo("OSSINDEX", alias.sonatypeId);
211-
} else if (vulnSource !== "SNYK" && alias.snykId) {
212-
return $common.resolveSourceVulnInfo("SNYK", alias.snykId);
213-
} else if (vulnSource !== "OSV" && alias.osvId) {
214-
return $common.resolveSourceVulnInfo("OSV", alias.osvId);
215-
} else if (vulnSource !== "GSD" && alias.gsdId) {
216-
return $common.resolveSourceVulnInfo("GSD", alias.gsdId);
217-
} else if (vulnSource !== "VULNDB" && alias.vulnDbId) {
218-
return $common.resolveSourceVulnInfo("VULNDB", alias.vulnDbId);
194+
$common.resolveVulnAliases = function resolveVulnAliases(vulnSource, aliases) {
195+
if (!vulnSource || !aliases) {
196+
return [];
219197
}
198+
199+
let resolvedAliases = aliases
200+
.flatMap((alias) => {
201+
const _resolvedAliases = [];
202+
if (vulnSource !== "INTERNAL" && alias.internalId) {
203+
_resolvedAliases.push($common.resolveSourceVulnInfo("INTERNAL", alias.internalId));
204+
}
205+
if (vulnSource !== "NVD" && alias.cveId) {
206+
_resolvedAliases.push($common.resolveSourceVulnInfo("NVD", alias.cveId));
207+
}
208+
if (vulnSource !== "GITHUB" && alias.ghsaId) {
209+
_resolvedAliases.push($common.resolveSourceVulnInfo("GITHUB", alias.ghsaId));
210+
}
211+
if (vulnSource !== "OSSINDEX" && alias.sonatypeId) {
212+
_resolvedAliases.push($common.resolveSourceVulnInfo("OSSINDEX", alias.sonatypeId));
213+
}
214+
if (vulnSource !== "SNYK" && alias.snykId) {
215+
_resolvedAliases.push($common.resolveSourceVulnInfo("SNYK", alias.snykId));
216+
}
217+
if (vulnSource !== "OSV" && alias.osvId) {
218+
_resolvedAliases.push($common.resolveSourceVulnInfo("OSV", alias.osvId));
219+
}
220+
if (vulnSource !== "GSD" && alias.gsdId) {
221+
_resolvedAliases.push($common.resolveSourceVulnInfo("GSD", alias.gsdId));
222+
}
223+
if (vulnSource !== "VULNDB" && alias.vulnDbId) {
224+
_resolvedAliases.push($common.resolveSourceVulnInfo("VULNDB", alias.vulnDbId));
225+
}
226+
return _resolvedAliases;
227+
});
228+
229+
// Deduplicate by vulnerability ID, so we're not showing the same ID more than once.
230+
resolvedAliases = [...new Map(resolvedAliases.map(alias => [alias.vulnId, alias])).values()];
231+
232+
// Sort aliases by vulnerability ID to achieve consistent output.
233+
return resolvedAliases
234+
.sort((a, b) => {
235+
if (a.vulnId < b.vulnId) {
236+
return -1;
237+
}
238+
if (a.vulnId > b.vulnId) {
239+
return 1;
240+
}
241+
return 0;
242+
});
220243
}
221244

222245
/**
@@ -473,7 +496,7 @@ export default {
473496
formatCweShortLabel: $common.formatCweShortLabel,
474497
formatAnalyzerLabel: $common.formatAnalyzerLabel,
475498
resolveSourceVulnInfo: $common.resolveSourceVulnInfo,
476-
resolveVulnAliasInfo: $common.resolveVulnAliasInfo,
499+
resolveVulnAliases: $common.resolveVulnAliases,
477500
makeAnalysisStateLabelFormatter: $common.makeAnalysisStateLabelFormatter,
478501
makeAnalysisJustificationLabelFormatter: $common.makeAnalysisJustificationLabelFormatter,
479502
componentClassifierLabelFormatter: $common.componentClassifierLabelFormatter,

src/views/portfolio/projects/ComponentVulnerabilities.vue

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@
4545
formatter(value, row, index) {
4646
if (typeof value !== 'undefined') {
4747
let label = "";
48-
for (let i=0; i<value.length; i++) {
49-
let alias = common.resolveVulnAliasInfo(row.source, value[i]);
50-
let url = xssFilters.uriInUnQuotedAttr("../vulnerabilities/" + alias.source + "/" + alias.vulnId);
48+
const aliases = common.resolveVulnAliases(row.source, value);
49+
for (let i=0; i<aliases.length; i++) {
50+
let alias = aliases[i];
51+
let url = xssFilters.uriInUnQuotedAttr("../../vulnerabilities/" + alias.source + "/" + alias.vulnId);
5152
label += common.formatSourceLabel(alias.source) + ` <a href="${url}">${xssFilters.inHTMLData(alias.vulnId)}</a>`
52-
if (i < value.length-1) label += "<br/><br/>"
53+
if (i < aliases.length-1) label += "<br/><br/>"
5354
}
5455
return label;
5556
}

src/views/portfolio/projects/Project.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<a href="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="fa fa-caret-down" aria-hidden="true" style="padding-left:10px; padding-right:10px; padding-top:3px; padding-bottom:3px;"></i></a>
1313
<ul class="dropdown-menu">
1414
<span v-for="p in availableProjectVersions">
15-
<b-dropdown-item :to="p.uuid">{{ p.version }}</b-dropdown-item>
15+
<b-dropdown-item :to="{name: 'Project', params: {'uuid': p.uuid}}">{{ p.version }}</b-dropdown-item>
1616
</span>
1717
</ul>
1818
</li>
@@ -21,7 +21,7 @@
2121
</div>
2222
<div class="text-muted text-lowercase font-weight-bold font-xs">
2323
<span v-for="tag in project.tags">
24-
<b-badge :to="{path: '../projects/', query: {'tag': tag.name}}" variant="tag">{{ tag.name }}</b-badge>
24+
<b-badge :to="{name: 'Projects', query: {'tag': tag.name}}" variant="tag">{{ tag.name }}</b-badge>
2525
</span>
2626
</div>
2727
</b-col>

src/views/portfolio/projects/ProjectFindings.vue

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,12 @@
144144
formatter(value, row, index) {
145145
if (typeof value !== 'undefined') {
146146
let label = "";
147-
for (let i=0; i<value.length; i++) {
148-
let alias = common.resolveVulnAliasInfo(row.vulnerability.source, value[i]);
147+
const aliases = common.resolveVulnAliases(row.vulnerability.source, value);
148+
for (let i=0; i<aliases.length; i++) {
149+
let alias = aliases[i];
149150
let url = xssFilters.uriInUnQuotedAttr("../../../vulnerabilities/" + alias.source + "/" + alias.vulnId);
150151
label += common.formatSourceLabel(alias.source) + ` <a href="${url}">${xssFilters.inHTMLData(alias.vulnId)}</a>`
151-
if (i < value.length-1) label += "<br/><br/>"
152+
if (i < aliases.length-1) label += "<br/><br/>"
152153
}
153154
return label;
154155
}
@@ -248,9 +249,9 @@
248249
<label>Aliases</label>
249250
<b-card class="font-weight-bold">
250251
<b-card-text>
251-
<span v-for="alias in finding.vulnerability.aliases">
252-
<b-link style="margin-right:1.0rem" :href="'/vulnerabilities/' + aliasLabel(finding.vulnerability.source, alias).source + '/' + aliasLabel(finding.vulnerability.source, alias).vulnId">{{aliasLabel(finding.vulnerability.source, alias).vulnId}}</b-link>
253-
</span>
252+
<span v-for="alias in resolveVulnAliases(finding.vulnerability.aliases)">
253+
<b-link style="margin-right:1.0rem" :href="'/vulnerabilities/' + alias.source + '/' + alias.vulnId">{{ alias.vulnId }}</b-link>
254+
</span>
254255
</b-card-text>
255256
</b-card>
256257
</div>
@@ -364,8 +365,8 @@
364365
},
365366
mixins: [permissionsMixin],
366367
methods: {
367-
aliasLabel: function(vulnSource, alias) {
368-
return common.resolveVulnAliasInfo(vulnSource, alias);
368+
resolveVulnAliases: function(aliases) {
369+
return common.resolveVulnAliases(this.source, aliases);
369370
},
370371
getAnalysis: function() {
371372
let queryString = "?project=" + projectUuid + "&component=" + this.finding.component.uuid + "&vulnerability=" + this.finding.vulnerability.uuid;

src/views/portfolio/projects/ProjectList.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,15 @@
184184
field: "tags",
185185
sortable: false,
186186
visible: false,
187+
routerFunc: () => this.$router, // Injecting $router directly causes recursion errors in Vue...
187188
formatter(value, row, index) {
189+
const router = this.routerFunc();
188190
let tag_string = ""
189191
if (row.tags) {
190-
tag_string = row.tags?.slice(0, 2).map(tag => common.formatProjectTagLabel(tag)).join(' ') || '';
192+
tag_string = row.tags?.slice(0, 2).map(tag => common.formatProjectTagLabel(router, tag)).join(' ') || '';
191193
if (row.tags.length > 2) {
192194
tag_string += ` <span class="d-none">`
193-
tag_string += row.tags.slice(2)?.map(tag => common.formatProjectTagLabel(tag)).join(' ');
195+
tag_string += row.tags.slice(2)?.map(tag => common.formatProjectTagLabel(router, tag)).join(' ');
194196
tag_string += `</span>`
195197
tag_string += `<a href="#" title="show all tags" class="badge badge-tag" onclick="this.previousElementSibling.classList.toggle('d-none')">…</a>`
196198
}

src/views/portfolio/vulnerabilities/Vulnerability.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
<span v-if="vulnerability.published" class="font-weight-bold font-xs" style="margin-right:1.2rem">{{prettyTimestamp}}</span>
4040
<span v-if="vulnerability.aliases && vulnerability.aliases.length > 0" class="font-weight-bold font-xs">
4141
Aliases:
42-
<span v-for="alias in vulnerability.aliases">
43-
<b-link style="margin-right:1.0rem" :href="`/vulnerabilities/${aliasLabel(alias).source}/${aliasLabel(alias).vulnId}`">{{ aliasLabel(alias).vulnId }}</b-link>
42+
<span v-for="alias in resolveVulnAliases(vulnerability.aliases)">
43+
<b-link style="margin-right:1.0rem" :href="`/vulnerabilities/${alias.source}/${alias.vulnId}`">{{ alias.vulnId }}</b-link>
4444
</span>
4545
</span>
4646
</b-card-text>
@@ -274,8 +274,8 @@
274274
cweLink: function(cwe) {
275275
return `https://cwe.mitre.org/data/definitions/${cwe.cweId}`;
276276
},
277-
aliasLabel: function(alias) {
278-
return common.resolveVulnAliasInfo(this.source, alias);
277+
resolveVulnAliases: function(aliases) {
278+
return common.resolveVulnAliases(this.source, aliases);
279279
},
280280
loadData: function () {
281281
let url = "";

src/views/portfolio/vulnerabilities/VulnerabilityDetailsModal.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
</b-row>
3232
<b-form-group :label="this.$t('message.aliases')">
3333
<div class="list-group">
34-
<span v-for="alias in vulnerability.aliases">
35-
<actionable-list-group-item :value="aliasLabel(alias).vulnId" :delete-icon="false"/>
34+
<span v-for="alias in resolveVulnAliases(vulnerability.aliases)">
35+
<actionable-list-group-item :value="alias.vulnId" :delete-icon="false"/>
3636
</span>
3737
<actionable-list-group-item :add-icon="!isReadonly" v-on:actionClicked="$root.$emit('bv::show::modal', 'selectCweModal')"/>
3838
</div>
@@ -897,8 +897,8 @@ export default {
897897
}
898898
},
899899
methods: {
900-
aliasLabel: function(alias) {
901-
return common.resolveVulnAliasInfo(this.vulnerability.source, alias);
900+
resolveVulnAliases: function(aliases) {
901+
return common.resolveVulnAliases(this.vulnerability.source, aliases);
902902
},
903903
onShow: function() {
904904
this.parseCvssV2Vector();

src/views/portfolio/vulnerabilities/VulnerabilityList.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,12 @@
6868
formatter(value, row, index) {
6969
if (typeof value !== 'undefined') {
7070
let label = "";
71-
for (let i=0; i<value.length; i++) {
72-
let alias = common.resolveVulnAliasInfo(row.source, value[i]);
71+
const aliases = common.resolveVulnAliases(value);
72+
for (let i=0; i<aliases.length; i++) {
73+
let alias = aliases[i];
7374
let url = xssFilters.uriInUnQuotedAttr("../vulnerabilities/" + alias.source + "/" + alias.vulnId);
7475
label += common.formatSourceLabel(alias.source) + ` <a href="${url}">${xssFilters.inHTMLData(alias.vulnId)}</a>`
75-
if (i < value.length-1) label += "<br/><br/>"
76+
if (i < aliases.length-1) label += "<br/><br/>"
7677
}
7778
return label;
7879
}

0 commit comments

Comments
 (0)