Skip to content

Commit 2b4c3d5

Browse files
author
Parth Shah
committed
fixes #54, fixes #53
1 parent 28e54e0 commit 2b4c3d5

File tree

3 files changed

+24
-12
lines changed

3 files changed

+24
-12
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tc-projects-service",
3-
"version": "1.4.0",
3+
"version": "1.4.1",
44
"description": "Projects microservice",
55
"main": "index.js",
66
"engines": {

src/routes/projects/list.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ const PROJECT_ATTACHMENT_ATTRIBUTES = _.without(
3030
'deletedAt',
3131
);
3232

33+
34+
const escapeEsKeyword = keyword => keyword.replace(/[+-=><!|(){}[&\]^"~*?:\\/]/g, '\\\\$&');
3335
/**
3436
* Parse the ES search criteria and prepare search request body
3537
*
@@ -44,11 +46,13 @@ const parseElasticSearchCriteria = (criteria, fields, order) => {
4446
type: ES_PROJECT_TYPE,
4547
size: criteria.limit,
4648
from: criteria.offset,
47-
sort: `${order[0]}:${order[1]}`,
4849
};
49-
let sourceInclude;
50-
50+
// best match / relevancy is the default sort w/ elasticsearch
51+
if (order[0].toLowerCase() !== 'best match') {
52+
searchCriteria.sort = `${order[0]}:${order[1]}`;
53+
}
5154

55+
let sourceInclude;
5256
if (_.get(fields, 'projects', null)) {
5357
sourceInclude = _.get(fields, 'projects');
5458
}
@@ -103,25 +107,26 @@ const parseElasticSearchCriteria = (criteria, fields, order) => {
103107
},
104108
});
105109
}
106-
107110
if (_.has(criteria, 'filters.keyword')) {
108111
// keyword is a full text search
112+
// escape special fields from keyword search
113+
const keyword = escapeEsKeyword(criteria.filters.keyword);
109114
fullTextQuery = {
110115
bool: {
111116
should: [
112117
{
113118
query_string: {
114-
query: `*${criteria.filters.keyword}*`,
119+
query: `*${keyword}*`,
115120
analyze_wildcard: true,
116-
fields: ['name', 'description', 'type'],
121+
fields: ['name^3', 'description', 'type'], // boost name field
117122
},
118123
},
119124
{
120125
nested: {
121126
path: 'members',
122127
query: {
123128
query_string: {
124-
query: `*${criteria.filters.keyword}*`,
129+
query: `*${keyword}*`,
125130
analyze_wildcard: true,
126131
fields: ['members.email', 'members.handle', 'members.firstName', 'members.lastName'],
127132
},
@@ -188,6 +193,7 @@ module.exports = [
188193
sort += ' asc';
189194
}
190195
const sortableProps = [
196+
'best match',
191197
'createdAt', 'createdAt asc', 'createdAt desc',
192198
'updatedAt', 'updatedAt asc', 'updatedAt desc',
193199
'id', 'id asc', 'id desc',

src/routes/projects/update.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const updateProjectValdiations = {
4343
name: Joi.string(),
4444
description: Joi.string().allow(null).allow('').optional(),
4545
billingAccountId: Joi.number().positive(),
46+
directProjectId: Joi.number().positive().allow(null),
4647
status: Joi.any().valid(_.values(PROJECT_STATUS)),
4748
estimatedPrice: Joi.number().precision(2).positive().allow(null),
4849
actualPrice: Joi.number().precision(2).positive(),
@@ -79,7 +80,7 @@ const updateProjectValdiations = {
7980
};
8081

8182
// NOTE- decided to disable all additional checks for now.
82-
const validateUpdates = (existingProject) => {
83+
const validateUpdates = (existingProject, updatedProps, authUser) => {
8384
const errors = [];
8485
switch (existingProject.status) {
8586
case PROJECT_STATUS.COMPLETED:
@@ -97,6 +98,12 @@ const validateUpdates = (existingProject) => {
9798
// }
9899
// }
99100
}
101+
console.log(_.intersection(authUser.roles, [USER_ROLE.MANAGER, USER_ROLE.TOPCODER_ADMIN]));
102+
if (_.has(updatedProps, 'directProjectId') &&
103+
_.intersection(authUser.roles, [USER_ROLE.MANAGER, USER_ROLE.TOPCODER_ADMIN]).length === 0) {
104+
errors.push('Don\'t have permission to update \'directProjectId\' property');
105+
}
106+
100107
return errors;
101108
};
102109

@@ -113,8 +120,7 @@ module.exports = [
113120
let updatedProps = req.body.param;
114121
const projectId = _.parseInt(req.params.projectId);
115122
// prune any fields that cannot be updated directly
116-
updatedProps = _.omit(updatedProps, ['createdBy', 'createdAt', 'updatedBy', 'updatedAt',
117-
'id', 'directProjectId']);
123+
updatedProps = _.omit(updatedProps, ['createdBy', 'createdAt', 'updatedBy', 'updatedAt', 'id']);
118124

119125
let previousValue;
120126
models.sequelize.transaction(() => models.Project.findOne({
@@ -133,7 +139,7 @@ module.exports = [
133139
}
134140
previousValue = _.clone(project.get({ plain: true }));
135141
// run additional validations
136-
const validationErrors = validateUpdates(previousValue, updatedProps);
142+
const validationErrors = validateUpdates(previousValue, updatedProps, req.authUser);
137143
if (validationErrors.length > 0) {
138144
const err = new Error('Unable to update project');
139145
_.assign(err, {

0 commit comments

Comments
 (0)