Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit 0a1cb8d

Browse files
author
ykohata
committed
Merge remote-tracking branch 'origin/technology-2014-10-16'
2 parents dc50ac3 + 99e19d2 commit 0a1cb8d

37 files changed

+1169
-192
lines changed

actions/challengeRegistration.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ var projectTrack = function (api, userId, challengeId, componentInfo, dbConnecti
363363
* @param {Function<err, data>} next The callback to be called after this function is done.
364364
*/
365365
var sendNotificationEmail = function (api, componentInfo, userId, activeForumCategoryId, challengeType, challengeId, dbConnectionMap, next) {
366-
var user, projectName, documentationDetails, submitURL, forumURL, umlToolInfo;
366+
var user, projectName, documentationDetails, submitURL, forumURL, umlToolInfo, reviewURL, template;
367367

368368
async.waterfall([
369369
function (cb) {
@@ -380,7 +380,10 @@ var sendNotificationEmail = function (api, componentInfo, userId, activeForumCat
380380
user = result[0];
381381
projectName = componentInfo.project_name + api.helper.getPhaseName(componentInfo.phase_id) + ' Contest';
382382
documentationDetails = '';
383-
submitURL = process.env.TC_SOFTWARE_SERVER_NAME + '/review';
383+
// we need to set up a new environment variable for the web server name specifici to each environment
384+
//submitURL = process.env.TC_ACTIVATION_SERVER_NAME + '/challenge-details/' + challengeId + '/submit/';
385+
submitURL = 'https://www.topcoder.com/challenge-details/' + challengeId + '/submit/';
386+
reviewURL = process.env.TC_SOFTWARE_SERVER_NAME + '/review';
384387

385388
if (componentInfo.phase_id === 112) {
386389
documentationDetails = '(see the Design Phase Documents thread)';
@@ -395,13 +398,15 @@ var sendNotificationEmail = function (api, componentInfo, userId, activeForumCat
395398

396399
if (challengeType === CHALLENGE_TYPE.DEVELOP) {
397400
forumURL = api.config.tcConfig.developForumsUrlPrefix + activeForumCategoryId;
398-
submitURL = process.env.TC_SOFTWARE_SERVER_NAME + '/review/actions/ViewProjectDetails?pid=' + challengeId;
401+
reviewURL = process.env.TC_SOFTWARE_SERVER_NAME + '/review/actions/ViewProjectDetails?pid=' + challengeId;
399402
} else if (challengeType === CHALLENGE_TYPE.DESIGN) {
400403
forumURL = api.config.tcConfig.studioForumsUrlPrefix + activeForumCategoryId;
401-
submitURL = process.env.TC_STUDIO_SERVER_NAME + '/?module=ViewContestDetails&ct=' + challengeId;
404+
reviewURL = process.env.TC_STUDIO_SERVER_NAME + '/?module=ViewContestDetails&ct=' + challengeId;
402405
}
403406

407+
template = 'registration_notification_email';
404408
if (challengeType === CHALLENGE_TYPE.DESIGN) {
409+
template = 'design_registration_notification_email';
405410
// Get forum type
406411
api.dataAccess.executeQuery('get_project_info',
407412
{
@@ -430,8 +435,9 @@ var sendNotificationEmail = function (api, componentInfo, userId, activeForumCat
430435
umlToolInfo : umlToolInfo,
431436
deadlineDate : api.helper.formatDateWithTimezone(componentInfo.initial_submission_date),
432437
submitURL : submitURL,
433-
template : 'registration_notification_email',
434-
toAddress : user.email,
438+
reviewURL : reviewURL,
439+
template : template,
440+
toAddress : user.address,
435441
senderName : "TC API"
436442
}, 'default');
437443
cb();

actions/rss.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,17 @@ function getChallengesRSS(api, connection, next) {
113113
},
114114
function (cb) {
115115
if (!_.isUndefined(technologies)) {
116-
helper.getCatalogCachedValue(technologies.split(','), dbConnectionMap, 'technologies', cb);
116+
helper.getCatalogCachedValue(technologies.split(',').map(function (s) { return s.toLowerCase().toString(); }), dbConnectionMap, 'technologies', cb);
117117
} else {
118118
cb(null, null);
119119
}
120120
},
121121
function (id, cb) {
122-
if (_.isDefined(techId)) {
122+
if (_.isDefined(id)) {
123123
techId = id;
124124
}
125125
if (!_.isUndefined(platforms)) {
126-
helper.getCatalogCachedValue(platforms.split(','), dbConnectionMap, 'platforms', cb);
126+
helper.getCatalogCachedValue(platforms.split(',').map(function (s) { return s.toLowerCase().toSource(); }), dbConnectionMap, 'platforms', cb);
127127
} else {
128128
cb(null, null);
129129
}

actions/user.js

Lines changed: 191 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
/*
22
* Copyright (C) 2014 TopCoder Inc., All Rights Reserved.
33
*
4-
* @version 1.0
5-
* @author muzehyun
4+
* @version 1.2
5+
* @author muzehyun, Ghost_141
6+
* Changes in 1.1:
7+
* - Implement user activation email api.
8+
* Changes in 1.2:
9+
* - Implement get user identity api.
610
*/
711
'use strict';
812
var async = require('async');
@@ -12,6 +16,18 @@ var ForbiddenError = require('../errors/ForbiddenError');
1216
var UnauthorizedError = require('../errors/UnauthorizedError');
1317
var IllegalArgumentError = require('../errors/IllegalArgumentError');
1418

19+
/**
20+
* The activation email subject.
21+
* @since 1.1
22+
*/
23+
var activationEmailSubject = "Topcoder User Registration Activation";
24+
25+
/**
26+
* The activation email sender name.
27+
* @since 1.1
28+
*/
29+
var activationEmailSenderName = "Topcoder API";
30+
1531
/**
1632
* It validates activation code and retrieves user id from activation code
1733
* @param {String} activationCode - activation code string
@@ -27,6 +43,16 @@ function getCoderId(activationCode, helper) {
2743
return 0;
2844
}
2945

46+
/**
47+
* Get cache key for user resend times in cache.
48+
* @param {String} handle - The handle of user.
49+
* @returns {string} The cache key.
50+
* @since 1.1
51+
*/
52+
function getCacheKeyForResendTimes(handle) {
53+
return 'user-activation-' + handle;
54+
}
55+
3056
/**
3157
* The API for activate user
3258
*/
@@ -121,8 +147,12 @@ exports.activateUser = {
121147
};
122148
// send email
123149
api.tasks.enqueue("sendEmail", emailParams, 'default');
150+
124151
result = { success: true };
125-
cb();
152+
// Remove cache from resend times from server.
153+
api.cache.destroy(getCacheKeyForResendTimes(handle), function () {
154+
cb();
155+
});
126156
}
127157
], function (err) {
128158
if (err) {
@@ -134,3 +164,161 @@ exports.activateUser = {
134164
});
135165
}
136166
};
167+
168+
/**
169+
* Handle user activation email here.
170+
* @param {Object} api - The api object.
171+
* @param {Object} connection - The database connection object map.
172+
* @param {Function} next - The callback function.
173+
* @since 1.1
174+
*/
175+
function userActivationEmail(api, connection, next) {
176+
var helper = api.helper, caller = connection.caller, currentResendTimes, activationCode,
177+
dbConnectionMap = connection.dbConnectionMap,
178+
cacheKey = 'user-activation-' + caller.handle;
179+
180+
async.waterfall([
181+
function (cb) {
182+
cb(helper.checkMember(connection, 'You must login for this endpoint.'));
183+
},
184+
function (cb) {
185+
api.dataAccess.executeQuery('check_user_activated', { handle: caller.handle }, dbConnectionMap, cb);
186+
},
187+
function (rs, cb) {
188+
if (rs[0].status === 'A') {
189+
cb(new BadRequestError("You're already activated."));
190+
return;
191+
}
192+
helper.getCachedValue(cacheKey, cb);
193+
},
194+
function (resendTimes, cb) {
195+
if (_.isUndefined(resendTimes)) {
196+
// We need to send the activation email and store the resend times.
197+
currentResendTimes = 0;
198+
} else {
199+
if (resendTimes >= api.config.tcConfig.userActivationResendLimit) {
200+
cb(new BadRequestError('Sorry, you already reached the limit of resend times. Please contact for support.'));
201+
return;
202+
}
203+
currentResendTimes = resendTimes;
204+
}
205+
api.dataAccess.executeQuery('get_user_email_and_handle', { userId: caller.userId }, dbConnectionMap, cb);
206+
},
207+
function (rs, cb) {
208+
activationCode = helper.generateActivationCode(caller.userId);
209+
api.tasks.enqueue("sendEmail",
210+
{
211+
subject : activationEmailSubject,
212+
activationCode : activationCode,
213+
template : 'activation_email',
214+
toAddress : rs[0].address,
215+
fromAddress : process.env.TC_EMAIL_ACCOUNT,
216+
senderName : activationEmailSenderName,
217+
url : process.env.TC_ACTIVATION_SERVER_NAME + '/reg2/activate.action?code=' + activationCode,
218+
userHandle : rs[0].handle
219+
}, 'default');
220+
api.cache.save(cacheKey, currentResendTimes + 1, api.config.tcConfig.userActivationCacheLifeTime,
221+
function (err) {
222+
cb(err);
223+
});
224+
}
225+
], function (err) {
226+
if (err) {
227+
helper.handleError(api, connection, err);
228+
} else {
229+
connection.response = {
230+
success: true
231+
};
232+
}
233+
next(connection, true);
234+
});
235+
}
236+
237+
/**
238+
* The API for activate user email.
239+
* @since 1.1
240+
*/
241+
exports.userActivationEmail = {
242+
name: 'userActivationEmail',
243+
description: 'Trigger sending user activation email.',
244+
inputs: {
245+
required: [],
246+
optional: []
247+
},
248+
blockedConnectionTypes: [],
249+
outputExample: {},
250+
version: 'v2',
251+
transaction: 'read',
252+
databases: ['common_oltp'],
253+
cacheEnabled: false,
254+
run: function (api, connection, next) {
255+
if (connection.dbConnectionMap) {
256+
api.log('Execute userActivationEmail#run', 'debug');
257+
userActivationEmail(api, connection, next);
258+
} else {
259+
api.helper.handleNoConnection(api, connection, next);
260+
}
261+
}
262+
};
263+
264+
/**
265+
* Get user identity information api.
266+
* @param {Object} api - The api object.
267+
* @param {Object} connection - The database connection map object.
268+
* @param {Function} next - The callback function.
269+
* @since 1.2
270+
*/
271+
function getUserIdentity(api, connection, next) {
272+
var helper = api.helper, caller = connection.caller, dbConnectionMap = connection.dbConnectionMap, response;
273+
async.waterfall([
274+
function (cb) {
275+
cb(helper.checkMember(connection, 'You need login for this endpoint.'));
276+
},
277+
function (cb) {
278+
api.dataAccess.executeQuery('get_user_email_and_handle', { userId: caller.userId }, dbConnectionMap, cb);
279+
},
280+
function (rs, cb) {
281+
response = {
282+
uid: caller.userId,
283+
handle: rs[0].handle,
284+
email: rs[0].address
285+
};
286+
cb();
287+
}
288+
], function (err) {
289+
if (err) {
290+
helper.handleError(api, connection, err);
291+
} else {
292+
connection.response = response;
293+
}
294+
next(connection, true);
295+
});
296+
297+
}
298+
299+
/**
300+
* The API for activate user
301+
* @since 1.2
302+
*/
303+
exports.getUserIdentity = {
304+
name: 'getUserIdentity',
305+
description: 'Get user identity information',
306+
inputs: {
307+
required: [],
308+
optional: []
309+
},
310+
blockedConnectionTypes: [],
311+
outputExample: {},
312+
version: 'v2',
313+
transaction: 'read',
314+
databases: ['common_oltp'],
315+
cacheEnabled: false,
316+
run: function (api, connection, next) {
317+
if (connection.dbConnectionMap) {
318+
api.log('getUserIdentity#run', 'debug');
319+
getUserIdentity(api, connection, next);
320+
} else {
321+
api.helper.handleNoConnection(api, connection, next);
322+
}
323+
}
324+
};

0 commit comments

Comments
 (0)