Skip to content

Commit 049f4dc

Browse files
author
tcchhabra
committed
fix for issue #3740 feedback
1 parent f8ecc6b commit 049f4dc

File tree

2 files changed

+62
-23
lines changed

2 files changed

+62
-23
lines changed

src/routes/projects/list.js

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -62,28 +62,11 @@ const SUPPORTED_FILTERS = [
6262

6363
const escapeEsKeyword = keyword => keyword.replace(/[+-=><!|(){}[&\]^"~*?:\\/]/g, '\\\\$&');
6464

65-
/**
66-
* ES need to skip special chars else it is considered as RegEx
67-
*
68-
* @param {String} query query being searched for
69-
* @return {String} result after parsing
70-
*/
71-
function escapeElasticsearchQuery(query) {
72-
const chars = ['\\', '+', '-', '&&', '||', '!', '(', ')', '{', '}', '[', ']',
73-
'^', '"', '~', '*', '?', ':', '/', '<', '>'];
74-
let result = query;
75-
_.forEach(chars, (item) => {
76-
result = result.replace(item, `\\${item}`);
77-
});
78-
return result;
79-
}
80-
8165
const buildEsFullTextQuery = (keyword, matchType, singleFieldName) => {
82-
const escapedKeyword = escapeElasticsearchQuery(keyword);
8366
let should = [
8467
{
8568
query_string: {
86-
query: (matchType === MATCH_TYPE_EXACT_PHRASE) ? escapedKeyword : `*${escapedKeyword}*`,
69+
query: (matchType === MATCH_TYPE_EXACT_PHRASE) ? keyword : `*${keyword}*`,
8770
analyze_wildcard: (matchType === MATCH_TYPE_WILDCARD),
8871
fields: ['name^5', 'description^3', 'type^2'],
8972
},
@@ -96,7 +79,7 @@ const buildEsFullTextQuery = (keyword, matchType, singleFieldName) => {
9679
path: 'details.utm',
9780
query: {
9881
query_string: {
99-
query: (matchType === MATCH_TYPE_EXACT_PHRASE) ? escapedKeyword : `*${escapedKeyword}*`,
82+
query: (matchType === MATCH_TYPE_EXACT_PHRASE) ? keyword : `*${keyword}*`,
10083
analyze_wildcard: (matchType === MATCH_TYPE_WILDCARD || matchType === MATCH_TYPE_SINGLE_FIELD),
10184
fields: ['details.utm.code^4'],
10285
},
@@ -110,7 +93,7 @@ const buildEsFullTextQuery = (keyword, matchType, singleFieldName) => {
11093
path: 'members',
11194
query: {
11295
query_string: {
113-
query: (matchType === MATCH_TYPE_EXACT_PHRASE) ? escapedKeyword : `*${escapedKeyword}*`,
96+
query: (matchType === MATCH_TYPE_EXACT_PHRASE) ? keyword : `*${keyword}*`,
11497
analyze_wildcard: (matchType === MATCH_TYPE_WILDCARD),
11598
fields: ['members.email', 'members.handle', 'members.firstName', 'members.lastName'],
11699
},
@@ -285,6 +268,22 @@ const setFilter = (value, keyword, fieldName) => {
285268
return buildEsQueryWithFilter(value, keyword, MATCH_TYPE_EXACT_PHRASE, fieldName);
286269
};
287270

271+
/**
272+
* ES need to skip special chars else it is considered as RegEx
273+
*
274+
* @param {String} query query being searched for
275+
* @return {String} result after parsing
276+
*/
277+
function escapeElasticsearchQuery(query) {
278+
const chars = ['\\', '+', '-', '&&', '||', '!', '(', ')', '{', '}', '[', ']',
279+
'^', '"', '~', '*', '?', ':', '/', '<', '>'];
280+
let result = query;
281+
_.forEach(chars, (item) => {
282+
result = result.replace(item, `\\${item}`);
283+
});
284+
return result;
285+
}
286+
288287
/**
289288
* Parse the ES search criteria and prepare search request body
290289
*
@@ -443,7 +442,7 @@ const parseElasticSearchCriteria = (criteria, fields, order) => {
443442

444443
if (!keyword) {
445444
// Not a specific field search nor an exact phrase search, do a wildcard match
446-
keyword = criteria.filters.keyword;
445+
keyword = escapeElasticsearchQuery(keywordCriterion);
447446
matchType = MATCH_TYPE_WILDCARD;
448447
}
449448

src/routes/projects/list.spec.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const data = [
2121
type: 'generic',
2222
billingAccountId: 1,
2323
name: 'test1',
24-
description: 'test project1',
24+
description: 'test project1 abc/d',
2525
status: 'active',
2626
details: {
2727
utm: {
@@ -1065,7 +1065,7 @@ describe('LIST Project', () => {
10651065
resJson.should.have.lengthOf(1);
10661066
resJson[0].should.have.property('description');
10671067
resJson[0].should.not.have.property('cancelReason');
1068-
resJson[0].description.should.be.eq('test project1');
1068+
resJson[0].description.should.be.eq('test project1 abc/d');
10691069
done();
10701070
}
10711071
});
@@ -1244,6 +1244,46 @@ describe('LIST Project', () => {
12441244
}
12451245
});
12461246
});
1247+
1248+
it('should find a project by quoted keyword with a special symbol in the name', (done) => {
1249+
request(server)
1250+
.get('/v5/projects/?keyword="abc/d"')
1251+
.set({
1252+
Authorization: `Bearer ${testUtil.jwts.admin}`,
1253+
})
1254+
.expect('Content-Type', /json/)
1255+
.expect(200)
1256+
.end((err, res) => {
1257+
if (err) {
1258+
done(err);
1259+
} else {
1260+
const resJson = res.body;
1261+
should.exist(resJson);
1262+
resJson.should.have.lengthOf(1);
1263+
done();
1264+
}
1265+
});
1266+
});
1267+
1268+
it('should find a project by keyword with a special symbol in the name', (done) => {
1269+
request(server)
1270+
.get('/v5/projects/?keyword=abc/d')
1271+
.set({
1272+
Authorization: `Bearer ${testUtil.jwts.admin}`,
1273+
})
1274+
.expect('Content-Type', /json/)
1275+
.expect(200)
1276+
.end((err, res) => {
1277+
if (err) {
1278+
done(err);
1279+
} else {
1280+
const resJson = res.body;
1281+
should.exist(resJson);
1282+
resJson.should.have.lengthOf(1);
1283+
done();
1284+
}
1285+
});
1286+
});
12471287
});
12481288
});
12491289
});

0 commit comments

Comments
 (0)