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' ;
812var async = require ( 'async' ) ;
@@ -12,6 +16,18 @@ var ForbiddenError = require('../errors/ForbiddenError');
1216var UnauthorizedError = require ( '../errors/UnauthorizedError' ) ;
1317var 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