Skip to content

Commit 894419b

Browse files
authored
Merge pull request #3404 from CVEProject/tat-3394-cve-id
Resolves #3394 Search and view basic information for a reserved and rejected CVE ID
2 parents e05a827 + b1662e0 commit 894419b

3 files changed

Lines changed: 109 additions & 34 deletions

File tree

src/stores/cveListSearch.js

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const useCveListSearchStore = defineStore('cveListSearch ', {
88
cveId: '',
99
from: 0,
1010
isArecord: undefined,
11+
isAnId: undefined,
1112
isSeachButtonDisabled: true,
1213
isIdOrRecordFound: true,
1314
isPublished: false,
@@ -19,6 +20,7 @@ export const useCveListSearchStore = defineStore('cveListSearch ', {
1920
isLookUpRecordServerError: false,
2021
isSearchServerError: false,
2122
query: '',
23+
idData: {},
2224
recordData: {},
2325
searchResults: [],
2426
searchType: true,
@@ -73,42 +75,44 @@ export const useCveListSearchStore = defineStore('cveListSearch ', {
7375
this.isSearching = true;
7476
try{
7577

76-
// * 2nd, query search service
78+
// * query search service
7779
this.totalExecutingRequests = 1;
7880
await this.getSearchResults();
7981

8082
// * Check if keyword is CVE ID
8183
if (this.isCveIdPattern()) {
8284
this.totalExecutingRequests = 2;
8385

84-
// 1st, lookup ID to get Record data, and continue to get CVE Records that mention that ID
86+
// lookup ID to get Record data
8587
this.cveId = this.query.toUpperCase();
86-
await this.getRecordData();
88+
await this.getRecordData();
8789
}
8890

8991
} catch (error) {
90-
throw new Error('search() >> error with getRecordData() and or getSearchResults()');
92+
// if record is not found, find potential reserved/rejected ID
93+
if (this.isCveIdPattern() && Object.keys(this.recordData).length === 0) {
94+
await this.getIdData();
95+
}
96+
97+
throw new Error('search() >> error with getSearchResults(), getRecordData(), or getIdData()');
9198
} finally {
9299
this.isSearching = false;
93100
this.setUpInitialPagination();
94101
}
95102
},
96103
async getRecordData() {
97104
this.isLookingUpRecord = true;
98-
const getRecordUrl = `/api/cve/${this.cveId}`;
105+
const getRecordUrl = `${useGenericGlobalsStore().currentServicesUrl}/api/cve/${this.cveId}`;
99106

100107
try {
101-
axios.defaults.baseURL = useGenericGlobalsStore().currentServicesUrl;
102108
const response = await axios.get(getRecordUrl);
103109
const cveRecordData = response?.data || {};
104110
this.isArecord = true;
105-
this.isIdOrRecordFound = false;
111+
this.isIdOrRecordFound = true;
106112

107113
// format description
108-
let descriptions = [];
109-
cveRecordData.containers?.cna?.descriptions.forEach((description) => {
110-
if (this.isEnglishLanguage(description.lang)) descriptions.push(this.processShowMoreShowLessDescription(description.value));
111-
});
114+
let descriptions = this.processDescriptionsField(cveRecordData);
115+
112116
let recordDataSummary = {
113117
cveId: cveRecordData?.cveMetadata?.cveId || 'No ID provided',
114118
cna: cveRecordData?.containers?.cna?.providerMetadata?.shortName || 'No CNA provided',
@@ -124,20 +128,42 @@ export const useCveListSearchStore = defineStore('cveListSearch ', {
124128
this.isRejected = true;
125129
}
126130

127-
} catch (e) {
131+
} catch (error) {
128132
this.isLookUpRecordServerError = true;
129133

130134
this.isPublished = false;
131135
this.isReserved = false;
132136
this.isRejected = false;
133137
this.isIdOrRecordFound = false;
134138
this.isArecord = false;
135-
throw new Error('getRecordData >> throwing wrroe')
139+
throw new Error('getRecordData >> throwing error');
136140
} finally {
137141
this.isLookingUpRecord = false;
138142
this.decrement('totalExecutingRequests');
139143
}
140144
},
145+
async getIdData() {
146+
const getIdUrl = `${useGenericGlobalsStore().currentServicesUrl}/api/cve-id/${this.cveId}`;
147+
try {
148+
const response = await axios.get(getIdUrl);
149+
const idData = response || {};
150+
this.isIdOrRecordFound = true;
151+
this.isAnId = true;
152+
if (idData.status === 200 && idData?.data?.error === undefined) {
153+
this.idData = idData.data;
154+
if (idData.state === 'RESERVED') {
155+
this.isReserved = true;
156+
this.isArecord = false;
157+
} else if (this.$store.state.idData.state === 'REJECTED') {
158+
this.isRejected = true;
159+
this.isArecord = false;
160+
}
161+
}
162+
163+
} catch (error) {
164+
throw new Error('getIdData >> throwing error');
165+
}
166+
},
141167
async getSearchResults() {
142168
this.isQueryingSearchService = true;
143169
const searchUrl = `${import.meta.env.VITE_API_BASE_URL}${import.meta.env.VITE_LIST_SEARCH_PATH}`;
@@ -168,7 +194,7 @@ export const useCveListSearchStore = defineStore('cveListSearch ', {
168194
cveId: result._id,
169195
cna: result?._source?.containers?.cna?.providerMetadata?.shortName || 'No CNA provided',
170196
cnaOrgId: result?._source?.containers?.cna?.providerMetadata?.orgId || '',
171-
descriptions: this.processDescriptionsField(result),
197+
descriptions: this.processDescriptionsField(result?._source),
172198
relevancyScore: result?._score
173199
});
174200
});
@@ -177,17 +203,17 @@ export const useCveListSearchStore = defineStore('cveListSearch ', {
177203

178204
this.searchResults = parsedResults;
179205
},
180-
processDescriptionsField(result){
206+
processDescriptionsField(recordData){
181207
let descriptions = [];
182-
if (result?._source?.cveMetadata?.state === "PUBLISHED") {
183-
result?._source?.containers?.cna?.descriptions.forEach((description) => {
208+
if (recordData.cveMetadata?.state === "PUBLISHED") {
209+
recordData.containers?.cna?.descriptions.forEach((description) => {
184210
if (this.isEnglishLanguage(description.lang)) descriptions.push(this.processShowMoreShowLessDescription(description.value));
185211
});
186-
} else if (result?._source?.cveMetadata?.state === "REJECTED") {
187-
result?._source?.containers?.cna?.rejectedReasons.forEach((rejectedReason) => {
212+
} else if (recordData.cveMetadata?.state === "REJECTED") {
213+
recordData.containers?.cna?.rejectedReasons.forEach((rejectedReason) => {
188214
if (this.isEnglishLanguage(rejectedReason.lang)) descriptions.push(this.processShowMoreShowLessDescription(rejectedReason.value));
189215
});
190-
} else {
216+
} else { // resevered/rejected ID w/o a CVE record does not have description, and that logic is handled in corresponding Vue file
191217
descriptions.push('No description provided');
192218
}
193219

src/views/CVERecord/CVERecord.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ export default {
214214
const errorToStr = error.toString() || '';
215215
if (!errorToStr.match(regex)) {
216216
usecveRecordStore().isPublished = false;
217-
usecveRecordStore().isReserved = false;
217+
usecveRecordStore().isReserved = false; // only a cve-id can be in a 'reserved' state; this should always be false
218218
usecveRecordStore().isRejected = false;
219219
this.handleServerError();
220220
}

src/views/CVERecord/SearchResults.vue

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,43 @@
3434
<p>You are accessing <span class="has-text-weight-bold">Production</span> data from {{ resultUrl }}</p>
3535
</div>
3636
</div>
37-
<div class="mb-3" v-if="Object.keys(cveListSearchStore.recordData).length > 0">
38-
<h2 class="title">CVE Record Found</h2>
37+
<h2 class="title">Search Results</h2>
38+
<div class="mb-3" v-if="hasRecordData || hasIdData">
39+
<h3 class="title is-size-5 mb-2"> CVE {{ getRecordOrIdLabel }} Found</h3>
3940
<p class="cve-help-text">
40-
See the CVE Record below. If you are searching for this CVE ID in other CVE Records, view the Search Results section below.
41+
<span v-if="hasRecordData">View the CVE {{ getRecordOrIdLabel }} below.</span>
42+
<span v-if="hasIdData">
43+
The <router-link to="/ResourcesSupport/Glossary#glossaryCVEID">CVE ID</router-link> below has no corresponding
44+
<router-link to="/ResourcesSupport/Glossary#glossaryRecord">CVE Record</router-link>.
45+
</span>
46+
If you are searching for this CVE ID in other CVE Records, view the <span class="has-text-weight-bold">Other Results</span> section below.
4147
</p>
42-
<div class="columns cve-columns is-variable is-1-desktop is-0-mobile mt-5 mr-2 mb-0 ml-2">
48+
<div class="columns cve-columns is-variable is-1-desktop is-0-mobile mt-0 mr-2 mb-4 ml-2">
4349
<div class="column cve-column">
4450
<div class="columns cve-columns">
4551
<div class="column cve-column">
46-
<router-link :to="`/CVERecord?id=${cveListSearchStore.recordData.cveId}`" target="_blank">{{ cveListSearchStore.recordData.cveId }}</router-link>
52+
<router-link v-if="hasRecordData"
53+
:to="`/CVERecord?id=${cveListSearchStore.recordData.cveId}`" target="_blank">
54+
{{ cveListSearchStore.recordData.cveId }}
55+
</router-link>
56+
<router-link v-if="hasIdData"
57+
:to="`/CVERecord?id=${cveListSearchStore.idData.cve_id}`" target="_blank">
58+
{{ cveListSearchStore.idData.cve_id}}
59+
</router-link>
4760
</div>
4861
<div class="column cve-column">
49-
<p>
62+
<p v-if="hasRecordData">
5063
<span>CNA: </span>
51-
{{ partnerStore.partnerShortLongNameMap[cveListSearchStore.recordData.cnaOrgId] ? partnerStore.partnerShortLongNameMap[cveListSearchStore.recordData.cnaOrgId] : cveListSearchStore.recordData.cna }}</p>
64+
{{ partnerStore.partnerShortLongNameMap[cveListSearchStore.recordData.cnaOrgId] ? partnerStore.partnerShortLongNameMap[cveListSearchStore.recordData.cnaOrgId] : cveListSearchStore.recordData.cna }}
65+
</p>
66+
<p v-if="hasIdData && cveListSearchStore?.idData?.state === 'REJECTED' && cveListSearchStore?.idData?.owning_cna">
67+
<span>Assigner: </span>
68+
<span>{{ cveListSearchStore.idData.owning_cna }}</span>
69+
</p>
5270
</div>
5371
</div>
5472
<div class="columns cve-columns">
55-
<div class="column cve-column">
73+
<div class="column cve-column" v-if="hasRecordData">
5674
<div v-for="(description, index) in cveListSearchStore.recordData.descriptions" :key="description.key" class="mb-0">
5775
<p v-if="!description.showMore" class="mb-0">
5876
{{ description.firstChunk }}<span v-if="!description.showMore && description.secondChunk.length > 0">...</span>
@@ -67,15 +85,27 @@
6785
</button>
6886
</div>
6987
</div>
88+
<div class="column cve-column" v-if="hasIdData">
89+
<p v-if="cveListSearchStore.idData.state === 'REJECTED'">
90+
This CVE ID was unused by the <router-link to="/ProgramOrganization/CNAs">CNA</router-link>
91+
</p>
92+
<p v-if="cveListSearchStore.idData.state === 'RESERVED'">
93+
This ID has been reserved by a <router-link to="/ProgramOrganization/CNAs">CNA</router-link> and its corresponding record
94+
will be updated by the assigning CNA once details are available. Learn more about the
95+
<router-link to="/ResourcesSupport/FAQs#pc_cve_recordsreserved_signify_in_cve_record">Reserved state</router-link>.
96+
</p>
97+
</div>
7098
</div>
7199
</div>
72100
</div>
73101
</div>
74102
<div id="cve-search-results-container" v-if="cveListSearchStore.totalSearchResultCount > 0">
75-
<h2 class="title">Search Results</h2>
76-
<p class="cve-help-text" v-if="Object.keys(cveListSearchStore.recordData).length > 0">
77-
Includes all record(s) that reference this CVE ID.
78-
</p>
103+
<div v-if="hasIdData || hasRecordData">
104+
<h3 class="title is-size-5 mb-2">Other Results</h3>
105+
<p class="cve-help-text">
106+
Includes all record(s) that reference this CVE ID.
107+
</p>
108+
</div>
79109
<div class="mt-4 mb-2">
80110
<p>
81111
<span>Showing </span>
@@ -123,7 +153,7 @@
123153
</div>
124154
</div>
125155
</div>
126-
<div v-if="Object.keys(cveListSearchStore.recordData).length > 0 || cveListSearchStore.totalSearchResultCount > 0">
156+
<div v-if="cveListSearchStore.totalSearchResultCount > 0">
127157
<div class="columns cve-columns" v-for="(result, resultIndex) in cveListSearchStore.searchResults" :key="result.index">
128158
<div class="column cve-column">
129159
<div class="column cve-column" :class="{'cve-top-border': resultIndex !== 0}">
@@ -282,6 +312,25 @@ function backToTop() {
282312
const websiteEnv = computed(() => {
283313
return import.meta.env.VITE_WEBSITE_ENVIRONMENT;
284314
});
315+
316+
let getRecordOrIdLabel = computed(() => {
317+
if (cveListSearchStore?.isArecord){
318+
return 'Record';
319+
} else if (Object.keys(cveListSearchStore.idData).length > 0) {
320+
return 'ID';
321+
} else {
322+
return '';
323+
}
324+
});
325+
326+
let hasRecordData = computed(() => {
327+
return Object.keys(cveListSearchStore.recordData).length > 0;
328+
});
329+
330+
331+
let hasIdData = computed(() => {
332+
return Object.keys(cveListSearchStore.idData).length > 0;
333+
});
285334
</script>
286335
287336
<style lang="scss">

0 commit comments

Comments
 (0)