Skip to content

Commit 7c548a1

Browse files
author
David T Rocca
committed
Switching between lookup and search
1 parent d815acc commit 7c548a1

8 files changed

Lines changed: 141 additions & 34 deletions

File tree

src/components/AdpVulnerabilityEnrichment.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@
208208

209209
<script>
210210
import { usecveRecordStore } from '@/stores/cveRecord.ts';
211+
import { useGenericGlobalsStore } from '@/stores/genericGlobals';
211212
import ProductStatus from '@/components/ProductStatus.vue';
212213
import CveRecordReferences from './CveRecordReferences.vue';
213214
@@ -252,7 +253,7 @@ export default {
252253
//to do
253254
adpShortName: this.containerObject.providerMetadata.shortName,
254255
dateUpdated: '',
255-
cveServicesBaseUrl: import.meta.env.VITE_CVE_SERVICES_BASE_URL,
256+
cveServicesBaseUrl: useGenericGlobalsStore().currentServicesUrl,
256257
usecveRecordStore: usecveRecordStore(),
257258
}
258259
},

src/components/cveRecordSearchModule.vue

Lines changed: 89 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
<template>
22
<div class="field mt-1">
3-
<div class="field has-addons mb-1">
4-
<div class="control is-expanded">
5-
<input v-model.trim="queryString" @keyup.enter="onKeyUpEnter" @keyup="validateQueryString" type="text" class="input cve-id-input"
6-
placeholder="Enter keywords (e.g.: CVE ID, sql injection, etc.)"/>
7-
</div>
8-
<div class="control">
9-
<button @click="validate"
3+
<div class="field has-addons">
4+
<div class="control">
5+
<span v-if="websiteEnv !== 'prd'" class="select cve-search-selector">
6+
<select v-model="searchType">
7+
<option>Search CVE List (Beta)</option>
8+
<option>Find a Test CVE Record/ID (Legacy)</option>
9+
</select>
10+
</span>
11+
</div>
12+
<div class="control is-expanded">
13+
<input v-if="searchTypeBoolean" v-model.trim="queryString" @keyup.enter="onKeyUpEnter" @keyup="validateQueryString" type="text" class="input cve-id-input"
14+
placeholder="Enter keywords (e.g.: CVE ID, sql injection, etc.)"/>
15+
<input v-else v-model="cveId" @keyup.enter="onKeyUpEnter" @keyup="validateQueryString" @blur="removeHelpText" type="text" class="input cve-id-input"
16+
placeholder="Enter CVE ID (CVE-YYYY-NNNN)"/>
17+
</div>
18+
<div class="control">
19+
<button @click="validate"
1020
class="button cve-button cve-button-accent-warm"
1121
:class="{'is-loading': cveListSearchStore.isSearching, 'disabled': cveListSearchStore.isSeachButtonDisabled}"
1222
:aria-disabled="cveListSearchStore.isSeachButtonDisabled">
1323
Search {{ websiteEnv === 'test' ? 'CVE List in Test' : ''}}
1424
</button>
15-
</div>
1625
</div>
26+
</div>
1727
<div class="notification is-warning is-light" role="alert" v-if="errorMessage.length > 0">
1828
<div class="is-flex is-align-content-flex-start">
1929
<p id="alertIcon" class="is-hidden">alert</p>
@@ -32,13 +42,28 @@
3242
import { useCveListSearchStore } from '@/stores/cveListSearch';
3343
import { computed, ref, watch } from 'vue';
3444
import { useRoute, useRouter } from 'vue-router';
45+
// Legacy Search Import
46+
import { usecveRecordStore } from '@/stores/cveRecord';
47+
import { useGenericGlobalsStore } from '@/stores/genericGlobals';
48+
3549
let cveListSearchStore = useCveListSearchStore();
3650
const route = useRoute();
3751
const router = useRouter();
3852
3953
let queryString = ref('');
4054
let errorMessage = ref('');
4155
56+
let cveGenericGlobalsStore = useGenericGlobalsStore();
57+
let cveRecordStore = usecveRecordStore();
58+
let searchType = ref('Search CVE List (Beta)');
59+
let cveId = cveRecordStore.cveId;
60+
61+
// this seems redundant, but it fixes an edge case.
62+
// if a user searches for a particular field, then on the results page flips the toggle, THEN refreshes without searching, this will keep the correct helper text showing.
63+
let searchTypeBoolean = computed(() => {
64+
return searchType.value == 'Search CVE List (Beta)' ? true : false;
65+
});
66+
4267
watch(
4368
() => route.query,
4469
() => {
@@ -54,7 +79,17 @@ watch(
5479
5580
5681
function startSearch() {
57-
if (queryString.value !== cveListSearchStore.query) {
82+
// We only want to flip the search item _When we actually do a search_ otherwise we should default back to what we were on a page refresh
83+
if (searchTypeBoolean.value) {
84+
cveGenericGlobalsStore.setUseSearch(true);
85+
cveGenericGlobalsStore.setCurrentServicesUrl(`https://${import.meta.env.VITE_CVE_SERVICES_BASE_URL}`)
86+
}
87+
else {
88+
cveGenericGlobalsStore.setUseSearch(false);
89+
cveGenericGlobalsStore.setCurrentServicesUrl("https://cveawg-test.mitre.org")
90+
}
91+
if (cveGenericGlobalsStore.useSearch) {
92+
if (queryString.value !== cveListSearchStore.query) {
5893
cveListSearchStore.$reset();
5994
cveListSearchStore.query = queryString.value;
6095
router.push({
@@ -63,24 +98,47 @@ function startSearch() {
6398
});
6499
cveListSearchStore.search();
65100
}
101+
} else {
102+
const lookupPath = `/CVERecord?id=${cveId}`;
103+
router.push(lookupPath)
104+
}
105+
66106
}
67107
68108
function validateQueryString() {
69-
const alphaNumericDashPattern = new RegExp(/^[a-zA-Z0-9 ]+$/, 'i').test(queryString.value);
70-
const cveIdPattern = new RegExp(/^CVE-\d{4}-\d{4,7}$/, 'i').test(queryString.value);
71-
72-
if (queryString.value.length > 0 && !alphaNumericDashPattern && !cveIdPattern) {
73-
cveListSearchStore.isSeachButtonDisabled = true;
74-
errorMessage.value = 'Only letters, numbers, and CVE IDs (CVE-YYYY-NNNN) are allowed.';
75-
cveListSearchStore.showHelpText = true;
76-
} else if (queryString.value.length === 0) {
77-
cveListSearchStore.isSeachButtonDisabled = true;
78-
errorMessage.value = '';
79-
cveListSearchStore.showHelpText = false;
109+
if (searchTypeBoolean.value) {
110+
const alphaNumericDashPattern = new RegExp(/^[a-zA-Z0-9 ]+$/, 'i').test(queryString.value);
111+
const cveIdPattern = new RegExp(/^CVE-\d{4}-\d{4,7}$/, 'i').test(queryString.value);
112+
113+
if (queryString.value.length > 0 && !alphaNumericDashPattern && !cveIdPattern) {
114+
cveListSearchStore.isSeachButtonDisabled = true;
115+
errorMessage.value = 'Only letters, numbers, and CVE IDs (CVE-YYYY-NNNN) are allowed.';
116+
cveListSearchStore.showHelpText = true;
117+
} else if (queryString.value.length === 0) {
118+
cveListSearchStore.isSeachButtonDisabled = true;
119+
errorMessage.value = '';
120+
cveListSearchStore.showHelpText = false;
121+
} else {
122+
cveListSearchStore.isSeachButtonDisabled = false;
123+
errorMessage.value = '';
124+
cveListSearchStore.showHelpText = false;
125+
}
80126
} else {
81-
cveListSearchStore.isSeachButtonDisabled = false;
82-
errorMessage.value = '';
83-
cveListSearchStore.showHelpText = false;
127+
//Basic Checking
128+
const cveIdPattern = new RegExp(/^CVE-\d{4}-\d{4,7}$/, 'i').test(cveId);
129+
if (cveId.length > 0 && !cveIdPattern) {
130+
cveListSearchStore.isSeachButtonDisabled = true;
131+
errorMessage.value = 'Only CVE IDs (CVE-YYYY-NNNN) are allowed.';
132+
cveListSearchStore.showHelpText = true;
133+
} else if (cveId.length === 0) {
134+
cveListSearchStore.isSeachButtonDisabled = true;
135+
errorMessage.value = '';
136+
cveListSearchStore.showHelpText = false;
137+
} else {
138+
cveListSearchStore.isSeachButtonDisabled = false;
139+
errorMessage.value = '';
140+
cveListSearchStore.showHelpText = false;
141+
}
84142
}
85143
}
86144
@@ -89,10 +147,16 @@ function onKeyUpEnter() {
89147
}
90148
91149
function validate() {
150+
92151
validateQueryString();
93-
if (!cveListSearchStore.isSeachButtonDisabled) {
152+
if (cveGenericGlobalsStore.useSearch) {
153+
if (!cveListSearchStore.isSeachButtonDisabled) {
154+
startSearch();
155+
}
156+
} else {
94157
startSearch();
95158
}
159+
96160
}
97161
98162
const websiteEnv = computed(() => {
@@ -119,4 +183,5 @@ const websiteEnv = computed(() => {
119183
width: 470px;
120184
}
121185
}
186+
122187
</style>

src/stores/cveListSearch.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { defineStore } from 'pinia';
2+
import { useGenericGlobalsStore } from './genericGlobals';
23
import axios from 'axios';
34

45
export const useCveListSearchStore = defineStore('cveListSearch ', {
@@ -108,7 +109,7 @@ export const useCveListSearchStore = defineStore('cveListSearch ', {
108109
const getRecordUrl = `/api/cve/${this.cveId}`;
109110

110111
try {
111-
axios.defaults.baseURL = `https://${import.meta.env.VITE_CVE_SERVICES_BASE_URL}`;
112+
axios.defaults.baseURL = useCveListSearchStore().currentServicesUrl;
112113
const response = await axios.get(getRecordUrl);
113114
const cveRecordData = response?.data || {};
114115
this.isArecord = true;

src/stores/genericGlobals.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
import { defineStore } from 'pinia';
22

33
export const useGenericGlobalsStore = defineStore('genericGlobals', {
4-
state: () => {
4+
state: () => {
5+
const storedUseSearch = sessionStorage.getItem('useSearch');
6+
const storedCurrentServicesUrl = sessionStorage.getItem('currentServicesUrl');
57
return {
8+
useSearch: storedUseSearch ? JSON.parse(storedUseSearch) : true,
9+
currentServicesUrl: storedCurrentServicesUrl ? JSON.parse(storedCurrentServicesUrl) : `https://${import.meta.env.VITE_CVE_SERVICES_BASE_URL}`,
610
legacyCveWebsiteLink: 'https://cve.mitre.org/cve/search_cve_list.html'
11+
};
12+
},
13+
actions: {
14+
setUseSearch(value) {
15+
this.useSearch = value;
16+
sessionStorage.setItem('useSearch', JSON.stringify(value));
17+
},
18+
setCurrentServicesUrl(value) {
19+
this.currentServicesUrl = value;
20+
sessionStorage.setItem('currentServicesUrl', JSON.stringify(value));
721
}
8-
}
22+
},
923
});

src/views/CVERecord/CVERecord.vue

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,21 @@
2121
</div>
2222
<div v-else>
2323
<div v-if="usecveRecordStore.isIdOrRecordFound">
24+
<div class="notification is-warning is-light" role="alert">
25+
<div v-if="websiteEnv !== 'prd'" class="is-flex" style="justify-content: center;">
26+
<p id="alertIconCveRecordsRequestErrored" class="is-hidden">alert</p>
27+
<font-awesome-icon style="flex: 0 0 40px;" size="1x" icon="triangle-exclamation" role="img"
28+
aria-labelledby="alertIconCveRecordsRequestErrored" aria-hidden="false" />
29+
<p>You are viewing <strong>{{ usingProd }}</strong> data from&nbsp;</p>
30+
<a :href="resultUrl" target="_blank"> {{ resultUrl }}
31+
<span class="icon cve-icon-xxs">
32+
<p id="externalLinkIcon" class="is-hidden">external website</p>
33+
<font-awesome-icon icon="up-right-from-square"
34+
aria-labelledby="externalLinkIcon" aria-hidden="false"/>
35+
</span>
36+
</a>
37+
</div>
38+
</div>
2439
<PublishedRecord v-if="usecveRecordStore.isPublished"/>
2540
<RejectedRecordOrId v-if="usecveRecordStore.isRejected"/>
2641
<ReservedId v-if="usecveRecordStore.isReserved"/>
@@ -77,6 +92,9 @@ export default {
7792
},
7893
data() {
7994
return {
95+
isResultFromProd: false,
96+
// There is a special case when the website deals with some cached data. This ensures that the correct value is shown, even though it is not pretty
97+
resultUrl: this.GenericGlobalsStore.useSearch ? `https://${import.meta.env.VITE_CVE_SERVICES_BASE_URL}` : `https://cveawg-test.mitre.org`,
8098
usecveRecordStore: usecveRecordStore(),
8199
cveId: usecveRecordStore().cveId,
82100
showHelpText: false,
@@ -87,6 +105,9 @@ export default {
87105
};
88106
},
89107
computed: {
108+
usingProd() {
109+
return this.isResultFromProd ? 'Production' : 'Test'
110+
},
90111
isSearching() {
91112
return usecveRecordStore().isSearching;
92113
},
@@ -207,7 +228,7 @@ export default {
207228
208229
const getIdUrl = `/api/cve-id/${usecveRecordStore().cveId}`;
209230
try {
210-
axios.defaults.baseURL = `https://${import.meta.env.VITE_CVE_SERVICES_BASE_URL}`;
231+
axios.defaults.baseURL = this.GenericGlobalsStore.currentServicesUrl;
211232
const idData = await axios.get(getIdUrl);
212233
this.getIdStatusCode = 200;
213234
if (idData.status === 200 && idData?.data?.error === undefined) {
@@ -243,9 +264,14 @@ export default {
243264
}
244265
},
245266
async getRecordData() {
246-
const getRecordUrl = `https://${import.meta.env.VITE_CVE_SERVICES_BASE_URL}/api/cve/${usecveRecordStore().cveId}`;
267+
const getRecordUrl = `${this.GenericGlobalsStore.currentServicesUrl}/api/cve/${usecveRecordStore().cveId}`;
268+
if (this.GenericGlobalsStore.useSearch) {
269+
this.isResultFromProd = true;
270+
} else {
271+
this.isResultFromProd = false;
272+
}
273+
this.resultUrl = this.GenericGlobalsStore.currentServicesUrl
247274
const recordData = await axios.get(getRecordUrl);
248-
249275
if (!(typeof (recordData.data) === 'object')) {
250276
usecveRecordStore().isPublished = false;
251277
usecveRecordStore().isReserved = false;

src/views/CVERecord/PublishedRecord.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ export default {
153153
tags: [],
154154
},
155155
originalRecordData: usecveRecordStore().recordData || {},
156-
cveServicesBaseUrl: import.meta.env.VITE_CVE_SERVICES_BASE_URL,
156+
cveServicesBaseUrl: this.GenericGlobalsStore.currentServicesUrl,
157157
usecveRecordStore: usecveRecordStore(),
158158
cpe: {},
159159
cnaContainer: {},

src/views/CVERecord/RejectedRecordOrId.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export default {
118118
},
119119
originalRecordData: usecveRecordStore().recordData || {},
120120
originalIdData: usecveRecordStore().idData || {},
121-
cveServicesBaseUrl: import.meta.env.VITE_CVE_SERVICES_BASE_URL,
121+
cveServicesBaseUrl: this.GenericGlobalsStore.currentServicesUrl,
122122
usecveRecordStore: usecveRecordStore()
123123
};
124124
},

src/views/CVERecord/ReservedId.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export default {
7979
data() {
8080
return {
8181
isMessageExpanded: false,
82-
cveServicesBaseUrl: import.meta.env.VITE_CVE_SERVICES_BASE_URL,
82+
cveServicesBaseUrl: this.GenericGlobalsStore.currentServicesUrl,
8383
usecveRecordStore: usecveRecordStore()
8484
};
8585
},

0 commit comments

Comments
 (0)