diff --git a/src/routes/projects/list.js b/src/routes/projects/list.js index 8ca1279a..97402f40 100755 --- a/src/routes/projects/list.js +++ b/src/routes/projects/list.js @@ -268,6 +268,22 @@ const setFilter = (value, keyword, fieldName) => { return buildEsQueryWithFilter(value, keyword, MATCH_TYPE_EXACT_PHRASE, fieldName); }; +/** + * ES need to skip special chars else it is considered as RegEx + * + * @param {String} query query being searched for + * @return {String} result after parsing + */ + function escapeElasticsearchQuery(query) { + const chars = ['\\', '+', '-', '&&', '||', '!', '(', ')', '{', '}', '[', ']', + '^', '"', '~', '*', '?', ':', '/', '<', '>']; + let result = query; + _.forEach(chars, (item) => { + result = result.replace(item, `\\${item}`); + }); + return result; + } + /** * Parse the ES search criteria and prepare search request body * @@ -426,7 +442,7 @@ const parseElasticSearchCriteria = (criteria, fields, order) => { if (!keyword) { // Not a specific field search nor an exact phrase search, do a wildcard match - keyword = criteria.filters.keyword; + keyword = escapeElasticsearchQuery(keywordCriterion); matchType = MATCH_TYPE_WILDCARD; } diff --git a/src/routes/projects/list.spec.js b/src/routes/projects/list.spec.js index 9ebb3e13..373f4dbb 100644 --- a/src/routes/projects/list.spec.js +++ b/src/routes/projects/list.spec.js @@ -21,7 +21,7 @@ const data = [ type: 'generic', billingAccountId: 1, name: 'test1', - description: 'test project1', + description: 'test project1 abc/d', status: 'active', details: { utm: { @@ -1065,7 +1065,7 @@ describe('LIST Project', () => { resJson.should.have.lengthOf(1); resJson[0].should.have.property('description'); resJson[0].should.not.have.property('cancelReason'); - resJson[0].description.should.be.eq('test project1'); + resJson[0].description.should.be.eq('test project1 abc/d'); done(); } }); @@ -1244,6 +1244,46 @@ describe('LIST Project', () => { } }); }); + + it('should find a project by quoted keyword with a special symbol in the name', (done) => { + request(server) + .get('/v5/projects/?keyword="abc/d"') + .set({ + Authorization: `Bearer ${testUtil.jwts.admin}`, + }) + .expect('Content-Type', /json/) + .expect(200) + .end((err, res) => { + if (err) { + done(err); + } else { + const resJson = res.body; + should.exist(resJson); + resJson.should.have.lengthOf(1); + done(); + } + }); + }); + + it('should find a project by keyword with a special symbol in the name', (done) => { + request(server) + .get('/v5/projects/?keyword=abc/d') + .set({ + Authorization: `Bearer ${testUtil.jwts.admin}`, + }) + .expect('Content-Type', /json/) + .expect(200) + .end((err, res) => { + if (err) { + done(err); + } else { + const resJson = res.body; + should.exist(resJson); + resJson.should.have.lengthOf(1); + done(); + } + }); + }); }); }); });