Skip to content

Commit 20e71c9

Browse files
committed
Merge branch 'dev' into feature/milestone-pausing
# Conflicts: # config/default.json
2 parents dfc0c41 + d206ad1 commit 20e71c9

File tree

11 files changed

+124
-61
lines changed

11 files changed

+124
-61
lines changed

config/custom-environment-variables.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,6 @@
4949
"connectUrl": "CONNECT_URL",
5050
"accountsAppUrl": "ACCOUNTS_APP_URL",
5151
"inviteEmailSubject": "INVITE_EMAIL_SUBJECT",
52-
"inviteEmailSectionTitle": "INVITE_EMAIL_SECTION_TITLE"
52+
"inviteEmailSectionTitle": "INVITE_EMAIL_SECTION_TITLE",
53+
"SSO_REFCODES": "SSO_REFCODES"
5354
}

config/default.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"connectUrl":"https://connect.topcoder-dev.com",
5959
"accountsAppUrl": "https://accounts.topcoder-dev.com",
6060
"MAX_REVISION_NUMBER": 100,
61-
"UNIQUE_GMAIL_VALIDATION": true,
61+
"UNIQUE_GMAIL_VALIDATION": false,
62+
"SSO_REFCODES": "[]",
6263
"VALID_STATUSES_BEFORE_PAUSED": "[\"active\"]"
6364
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--
2+
-- UPDATE EXISTING TABLES:
3+
-- project_estimations:
4+
-- added column `quantity`
5+
6+
--
7+
-- product_templates
8+
9+
-- Add new column
10+
ALTER TABLE project_estimations ADD COLUMN "quantity" int DEFAULT 1;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--
2+
-- FIX for 20190316_extract_scope_from_project_templates.sql
3+
-- apply created auto-increments sequences to `id` columns
4+
5+
ALTER TABLE form
6+
ALTER COLUMN id SET DEFAULT nextval('form_id_seq');
7+
8+
ALTER TABLE price_config
9+
ALTER COLUMN id SET DEFAULT nextval('price_config_id_seq');
10+
11+
ALTER TABLE plan_config
12+
ALTER COLUMN id SET DEFAULT nextval('plan_config_id_seq');

src/events/busApi.js

Lines changed: 81 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { EVENT, BUS_API_EVENT, PROJECT_STATUS, PROJECT_PHASE_STATUS, PROJECT_MEM
55
from '../constants';
66
import { createEvent } from '../services/busApi';
77
import models from '../models';
8-
import getTopcoderProjectMembers from '../util';
8+
import util from '../util';
99

1010
/**
1111
* Map of project status and event name sent to bus api
@@ -367,7 +367,7 @@ module.exports = (app, logger) => {
367367
userId: req.authUser.userId,
368368
initiatorUserId: req.authUser.userId,
369369
allowedUsers: created.status === PROJECT_PHASE_STATUS.DRAFT ?
370-
getTopcoderProjectMembers(project.members) : null,
370+
util.getTopcoderProjectMembers(project.members) : null,
371371
}, logger);
372372
return sendPlanReadyEventIfNeeded(req, project, created);
373373
}).catch(err => null); // eslint-disable-line no-unused-vars
@@ -393,7 +393,7 @@ module.exports = (app, logger) => {
393393
userId: req.authUser.userId,
394394
initiatorUserId: req.authUser.userId,
395395
allowedUsers: deleted.status === PROJECT_PHASE_STATUS.DRAFT ?
396-
getTopcoderProjectMembers(project.members) : null,
396+
util.getTopcoderProjectMembers(project.members) : null,
397397
}, logger);
398398
}).catch(err => null); // eslint-disable-line no-unused-vars
399399
});
@@ -446,7 +446,7 @@ module.exports = (app, logger) => {
446446
userId: req.authUser.userId,
447447
initiatorUserId: req.authUser.userId,
448448
allowedUsers: updated.status === PROJECT_PHASE_STATUS.DRAFT ?
449-
getTopcoderProjectMembers(project.members) : null,
449+
util.getTopcoderProjectMembers(project.members) : null,
450450
}, logger));
451451
events.forEach((event) => { eventsMap[event] = true; });
452452
}
@@ -493,7 +493,7 @@ module.exports = (app, logger) => {
493493
userId: req.authUser.userId,
494494
initiatorUserId: req.authUser.userId,
495495
allowedUsers: updated.status === PROJECT_PHASE_STATUS.DRAFT ?
496-
getTopcoderProjectMembers(project.members) : null,
496+
util.getTopcoderProjectMembers(project.members) : null,
497497
}, logger);
498498
}
499499
}).catch(err => null); // eslint-disable-line no-unused-vars
@@ -716,63 +716,87 @@ module.exports = (app, logger) => {
716716
app.on(EVENT.ROUTING_KEY.PROJECT_MEMBER_INVITE_CREATED, ({ req, userId, email, status, role }) => {
717717
logger.debug('receive PROJECT_MEMBER_INVITE_CREATED event');
718718
const projectId = _.parseInt(req.params.projectId);
719-
720-
if (status === INVITE_STATUS.REQUESTED) {
721-
createEvent(BUS_API_EVENT.PROJECT_MEMBER_INVITE_REQUESTED, {
722-
projectId,
723-
userId,
724-
email,
725-
role,
726-
initiatorUserId: req.authUser.userId,
727-
}, logger);
728-
} else {
729-
// send event to bus api
730-
createEvent(BUS_API_EVENT.PROJECT_MEMBER_INVITE_CREATED, {
731-
projectId,
732-
userId,
733-
email,
734-
role,
735-
initiatorUserId: req.authUser.userId,
736-
}, logger);
737-
}
719+
models.Project.findOne({
720+
where: { id: projectId },
721+
})
722+
.then((project) => {
723+
logger.debug(util.isSSO);
724+
if (status === INVITE_STATUS.REQUESTED) {
725+
createEvent(BUS_API_EVENT.PROJECT_MEMBER_INVITE_REQUESTED, {
726+
projectId,
727+
userId,
728+
email,
729+
role,
730+
initiatorUserId: req.authUser.userId,
731+
isSSO: util.isSSO(project),
732+
}, logger);
733+
} else {
734+
// send event to bus api
735+
logger.debug(JSON.stringify({
736+
projectId,
737+
userId,
738+
email,
739+
role,
740+
initiatorUserId: req.authUser.userId,
741+
isSSO: util.isSSO(project),
742+
}));
743+
createEvent(BUS_API_EVENT.PROJECT_MEMBER_INVITE_CREATED, {
744+
projectId,
745+
userId,
746+
email,
747+
role,
748+
initiatorUserId: req.authUser.userId,
749+
isSSO: util.isSSO(project),
750+
}, logger);
751+
}
752+
}).catch(err => logger.error(err)); // eslint-disable-line no-unused-vars
738753
});
739754

740755
app.on(EVENT.ROUTING_KEY.PROJECT_MEMBER_INVITE_UPDATED, ({ req, userId, email, status, role, createdBy }) => {
741756
logger.debug('receive PROJECT_MEMBER_INVITE_UPDATED event');
742757
const projectId = _.parseInt(req.params.projectId);
743758

744-
if (status === INVITE_STATUS.REQUEST_APPROVED) {
745-
// send event to bus api
746-
createEvent(BUS_API_EVENT.PROJECT_MEMBER_INVITE_APPROVED, {
747-
projectId,
748-
userId,
749-
originator: createdBy,
750-
email,
751-
role,
752-
status,
753-
initiatorUserId: req.authUser.userId,
754-
}, logger);
755-
} else if (status === INVITE_STATUS.REQUEST_REJECTED) {
756-
// send event to bus api
757-
createEvent(BUS_API_EVENT.PROJECT_MEMBER_INVITE_REJECTED, {
758-
projectId,
759-
userId,
760-
originator: createdBy,
761-
email,
762-
role,
763-
status,
764-
initiatorUserId: req.authUser.userId,
765-
}, logger);
766-
} else {
767-
// send event to bus api
768-
createEvent(BUS_API_EVENT.PROJECT_MEMBER_INVITE_UPDATED, {
769-
projectId,
770-
userId,
771-
email,
772-
role,
773-
status,
774-
initiatorUserId: req.authUser.userId,
775-
}, logger);
776-
}
759+
models.Project.findOne({
760+
where: { id: projectId },
761+
})
762+
.then((project) => {
763+
logger.debug(util.isSSO);
764+
if (status === INVITE_STATUS.REQUEST_APPROVED) {
765+
// send event to bus api
766+
createEvent(BUS_API_EVENT.PROJECT_MEMBER_INVITE_APPROVED, {
767+
projectId,
768+
userId,
769+
originator: createdBy,
770+
email,
771+
role,
772+
status,
773+
initiatorUserId: req.authUser.userId,
774+
isSSO: util.isSSO(project),
775+
}, logger);
776+
} else if (status === INVITE_STATUS.REQUEST_REJECTED) {
777+
// send event to bus api
778+
createEvent(BUS_API_EVENT.PROJECT_MEMBER_INVITE_REJECTED, {
779+
projectId,
780+
userId,
781+
originator: createdBy,
782+
email,
783+
role,
784+
status,
785+
initiatorUserId: req.authUser.userId,
786+
isSSO: util.isSSO(project),
787+
}, logger);
788+
} else {
789+
// send event to bus api
790+
createEvent(BUS_API_EVENT.PROJECT_MEMBER_INVITE_UPDATED, {
791+
projectId,
792+
userId,
793+
email,
794+
role,
795+
status,
796+
initiatorUserId: req.authUser.userId,
797+
isSSO: util.isSSO(project),
798+
}, logger);
799+
}
800+
}).catch(err => null); // eslint-disable-line no-unused-vars
777801
});
778802
};

src/models/projectEstimation.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module.exports = function defineProjectHistory(sequelize, DataTypes) {
66
buildingBlockKey: { type: DataTypes.STRING, allowNull: false },
77
conditions: { type: DataTypes.STRING, allowNull: false },
88
price: { type: DataTypes.DOUBLE, allowNull: false },
9+
quantity: { type: DataTypes.INTEGER, allowNull: true },
910
minTime: { type: DataTypes.INTEGER, allowNull: false },
1011
maxTime: { type: DataTypes.INTEGER, allowNull: false },
1112
metadata: { type: DataTypes.JSON, allowNull: false, defaultValue: {} },

src/routes/projectMemberInvites/create.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ const sendInviteEmail = (req, projectId, invite) => {
162162
projectName: project.name,
163163
projectId,
164164
initiator,
165+
isSSO: util.isSSO(project),
165166
},
166167
],
167168
}],

src/routes/projectMemberInvites/create.spec.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ describe('Project Member Invite create', () => {
735735
});
736736
});
737737

738-
it('should return 201 and empty response when trying add already invited member by gmail email with dot',
738+
xit('should return 201 and empty response when trying add already invited member by gmail email with dot',
739739
(done) => {
740740
request(server)
741741
.post(`/v4/projects/${project1.id}/members/invite`)
@@ -762,7 +762,7 @@ describe('Project Member Invite create', () => {
762762
});
763763
});
764764

765-
it('should return 201 and empty response when trying add already invited member by gmail email without dot',
765+
xit('should return 201 and empty response when trying add already invited member by gmail email without dot',
766766
(done) => {
767767
request(server)
768768
.post(`/v4/projects/${project1.id}/members/invite`)
@@ -841,6 +841,7 @@ describe('Project Member Invite create', () => {
841841
projectId: project1.id,
842842
userId: 3,
843843
email: null,
844+
isSSO: false,
844845
})).should.be.true;
845846
done();
846847
});
@@ -888,6 +889,7 @@ describe('Project Member Invite create', () => {
888889
projectId: project1.id,
889890
userId: null,
890891
email: 'hello@world.com',
892+
isSSO: false,
891893
})).should.be.true;
892894
done();
893895
});

src/routes/projectMemberInvites/update.spec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ describe('Project member invite update', () => {
359359
userId: invite1.userId,
360360
status: INVITE_STATUS.ACCEPTED,
361361
email: null,
362+
isSSO: false,
362363
})).should.be.true;
363364
createEventSpy.secondCall.calledWith(BUS_API_EVENT.MEMBER_JOINED, sinon.match({
364365
projectId: project1.id,

src/routes/projects/create.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ const createProjectValdiations = {
6060
estimation: Joi.array().items(Joi.object().keys({
6161
conditions: Joi.string().required(),
6262
price: Joi.number().required(),
63+
quantity: Joi.number().optional(),
6364
minTime: Joi.number().integer().required(),
6465
maxTime: Joi.number().integer().required(),
6566
buildingBlockKey: Joi.string().required(),

src/util.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ const m2m = tcCoreLibAuth.m2m(config);
2828

2929
const util = _.cloneDeep(require('tc-core-library-js').util(config));
3030

31+
const ssoRefCodes = JSON.parse(config.get('SSO_REFCODES'));
32+
3133
// the client modifies the config object, so always passed the cloned object
3234
let esClient = null;
3335

@@ -468,6 +470,13 @@ _.assignIn(util, {
468470
*/
469471
getTopcoderProjectMembers: members => _(members).filter(m => m.role !== PROJECT_MEMBER_ROLE.CUSTOMER),
470472

473+
/**
474+
* Check if project is for SSO users
475+
* @param {Object} project project
476+
* @return {Boolean} is SSO project
477+
*/
478+
isSSO: project => ssoRefCodes.indexOf(_.get(project, 'details.utm.code')) > -1,
479+
471480
/**
472481
* Check if the following model exist
473482
* @param {Object} keyInfo key information, it includes version and key

0 commit comments

Comments
 (0)