From 81f83d7b94d82de4d1b4fea630b1345632837d42 Mon Sep 17 00:00:00 2001 From: Emre Date: Wed, 10 May 2023 17:55:05 +0300 Subject: [PATCH 1/2] include email in the response of helper method --- src/common/helper.js | 20 ++++++++++++-------- src/models/MemberProfile.js | 3 +++ src/services/ResourceService.js | 8 ++++---- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/common/helper.js b/src/common/helper.js index 58df8c8..19aa2e8 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -176,26 +176,30 @@ async function getMemberById (id) { * @param {String} handle The member handle * @returns {Promise} */ -async function getMemberIdByHandle (handle) { +async function getMemberDetailsByHandle (handle) { try { // logger.warn(`getMemberIdByHandle ${handle}`) const profile = await MemberProfile.query('handleLower').eq(_.toLower(handle)).exec().then(r => r[0]) - return profile.userId + return { memberId: profile.userId, email: profile.email } } catch (e) { // fall back to v3 api... - logger.warn(`Get MemberID by Handle from Dynamo Failed, trying v3 Members API. Error: ${JSON.stringify(e)}`) - return getMemberIdByHandleFromV3Members(handle) + logger.warn(`Get Member by Handle from Dynamo Failed, trying v3 Members API. Error: ${JSON.stringify(e)}`) + return getMemberDetailsByHandleFromV3Members(handle) } } -async function getMemberIdByHandleFromV3Members (handle) { +async function getMemberDetailsByHandleFromV3Members (handle) { let memberId + let email try { - logger.warn(`getMemberIdByHandle ${handle} from v5`) + logger.warn(`getMemberByHandle ${handle} from v5`) const res = await getRequest(`${config.MEMBER_API_URL}/${handle}`) if (_.get(res, 'body.userId')) { memberId = String(res.body.userId) } + if (_.get(res, 'body.email')) { + email = String(res.body.email) + } // handle return from v3 API, handle and memberHandle are the same under case-insensitive condition handle = _.get(res, 'body.handle') } catch (error) { @@ -209,7 +213,7 @@ async function getMemberIdByHandleFromV3Members (handle) { throw new errors.BadRequestError(`User with handle: ${handle} doesn't exist`) } - return memberId + return { memberId, email } } /** @@ -481,7 +485,7 @@ module.exports = { wrapExpress, autoWrapExpress, getMemberInfoById, - getMemberIdByHandle, + getMemberDetailsByHandle, checkIfExists, hasAdminRole, getById, diff --git a/src/models/MemberProfile.js b/src/models/MemberProfile.js index 583c2c8..42d5bfb 100644 --- a/src/models/MemberProfile.js +++ b/src/models/MemberProfile.js @@ -23,6 +23,9 @@ const schema = new Schema({ name: 'handleLower-index', project: true } + }, + email: { + type: String } }, { diff --git a/src/services/ResourceService.js b/src/services/ResourceService.js index 80c687d..03c8c65 100644 --- a/src/services/ResourceService.js +++ b/src/services/ResourceService.js @@ -245,7 +245,7 @@ async function init (currentUser, challengeId, resource, isCreated) { // get member information using v3 API const handle = resource.memberHandle - const memberId = await helper.getMemberIdByHandle(resource.memberHandle) + const { memberId, email } = await helper.getMemberDetailsByHandle(resource.memberHandle) // check if the resource is reviewer role and has already made a submission in the challenge if (resource.roleId === config.REVIEWER_RESOURCE_ROLE_ID || resource.roleId === config.ITERATIVE_REVIEWER_RESOURCE_ROLE_ID) { @@ -284,11 +284,11 @@ async function init (currentUser, challengeId, resource, isCreated) { } // skip phase dependency checks for tasks if (_.get(challenge, 'task.isTask', false)) { - return { resources, memberId, handle } + return { resources, memberId, handle, email, challenge } } // bypass phase dependency checks if the caller is an m2m/admin if (currentUser.isMachine || helper.hasAdminRole(currentUser)) { - return { resources, memberId, handle } + return { resources, memberId, handle, email, challenge } } // check phases dependencies const dependencies = await ResourceRolePhaseDependencyService.getDependencies({ resourceRoleId: resource.roleId }) @@ -316,7 +316,7 @@ async function init (currentUser, challengeId, resource, isCreated) { }) // return resources and the member id - return { resources, memberId, handle } + return { resources, memberId, handle, email, challenge } } /** From bab26fb78b0d6d882a44411b9b39f7502c8febc5 Mon Sep 17 00:00:00 2001 From: eisbilir Date: Wed, 10 May 2023 22:59:24 +0300 Subject: [PATCH 2/2] send registration email --- config/default.js | 9 +++++++++ src/services/ResourceService.js | 21 ++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/config/default.js b/config/default.js index fade308..0774e25 100644 --- a/config/default.js +++ b/config/default.js @@ -68,6 +68,15 @@ module.exports = { RESOURCE_DELETE_TOPIC: process.env.RESOURCE_DELETE_TOPIC || 'challenge.action.resource.delete', RESOURCE_ROLE_CREATE_TOPIC: process.env.RESOURCE_ROLE_CREATE_TOPIC || 'challenge.action.resource.role.create', RESOURCE_ROLE_UPDATE_TOPIC: process.env.RESOURCE_ROLE_UPDATE_TOPIC || 'challenge.action.resource.role.update', + EMAIL_NOTIFICATIN_TOPIC: process.env.EMAIL_NOTIFICATIN_TOPIC || 'external.action.email', + REGISTRATION_EMAIL: { + EMAIL_FROM: process.env.EMAIL_FROM || "no-reply@topcoder.com", + SENDGRID_TEMPLATE_ID: process.env.SENDGRID_TEMPLATE_ID || "d-b0593e8d64a84745905fb795523fde04", + SUBMIT_URL: process.env.SUBMIT_URL || "https://www.topcoder.com/challenges/:id/submit/", + REVIEW_APP_URL: process.env.REVIEW_APP_URL || "https://software.topcoder.com/review", + HELP_URL: process.env.HELP_URL || "https://help.topcoder.com", + SUPPORT_EMAIL: process.env.SUPPORT_EMAIL || "support@topcoder.com", + }, AUTOMATED_TESTING_NAME_PREFIX: process.env.AUTOMATED_TESTING_NAME_PREFIX || 'POSTMANE2E-' } diff --git a/src/services/ResourceService.js b/src/services/ResourceService.js index 03c8c65..56931f6 100644 --- a/src/services/ResourceService.js +++ b/src/services/ResourceService.js @@ -331,7 +331,7 @@ async function createResource (currentUser, resource) { // handle doesn't change in current version // Seems we don't need handle auto-correction(e.g. "THomaskranitsas"->"thomaskranitsas") - const { resources, memberId } = await init(currentUser, challengeId, resource, true) + const { resources, memberId, handle, email, challenge } = await init(currentUser, challengeId, resource, true) if (_.reduce(resources, (result, r) => _.toString(r.memberId) === _.toString(memberId) && r.roleId === resource.roleId ? true : result, @@ -358,6 +358,25 @@ async function createResource (currentUser, resource) { logger.debug(`Created resource: ${JSON.stringify(_.pick(ret, payloadFields))}`) await helper.postEvent(config.RESOURCE_CREATE_TOPIC, _.pick(ret, payloadFields)) + if (!_.get(challenge, 'task.isTask', false) && resource.roleId === config.SUBMITTER_RESOURCE_ROLE_ID) { + await helper.postEvent(config.EMAIL_NOTIFICATIN_TOPIC, { + from: config.REGISTRATION_EMAIL.EMAIL_FROM, + replyTo: config.REGISTRATION_EMAIL.EMAIL_FROM, + recipients: [email], + data: { + handle, + challengeName: challenge.name, + forum: _.get(challenge, 'discussions[0].url'), + submissionEndTime: _.get(_.find(challenge.phases, phase => phase.name === "Submission"), 'scheduledEndDate'), + submitUrl: _.replace(config.REGISTRATION_EMAIL.SUBMIT_URL, ':id', challengeId), + reviewAppUrl: config.REGISTRATION_EMAIL.REVIEW_APP_URL, + helpUrl: config.REGISTRATION_EMAIL.HELP_URL, + support: config.REGISTRATION_EMAIL.SUPPORT_EMAIL + }, + sendgrid_template_id: config.REGISTRATION_EMAIL.SENDGRID_TEMPLATE_ID, + version: "v3" + }) + } return ret } catch (err) {