@@ -1364,10 +1364,9 @@ function isDifferentPrizeSets(prizeSets = [], otherPrizeSets = []) {
1364
1364
/**
1365
1365
* Validate the winners array.
1366
1366
* @param {Array } winners the Winner Array
1367
- * @param {String } winchallengeIdners the challenge ID
1367
+ * @param {Array } challengeResources the challenge resources
1368
1368
*/
1369
- async function validateWinners ( winners , challengeId ) {
1370
- const challengeResources = await helper . getChallengeResources ( challengeId ) ;
1369
+ async function validateWinners ( winners , challengeResources ) {
1371
1370
const registrants = _ . filter ( challengeResources , ( r ) => r . roleId === config . SUBMITTER_ROLE_ID ) ;
1372
1371
for ( const prizeType of _ . values ( constants . prizeSetTypes ) ) {
1373
1372
const filteredWinners = _ . filter ( winners , ( w ) => w . type === prizeType ) ;
@@ -1410,6 +1409,55 @@ async function validateWinners(winners, challengeId) {
1410
1409
}
1411
1410
}
1412
1411
1412
+ /**
1413
+ * Task shouldn't be launched/completed when it is assigned to the current user self.
1414
+ * E.g: stop copilots from paying themselves, thus copilots will need to contact manager to launch/complete the task.
1415
+ * @param {Object } currentUser the user who perform operation
1416
+ * @param {Object } challenge the existing challenge
1417
+ * @param {Object } data the new input challenge data
1418
+ * @param {Array } challengeResources the challenge resources
1419
+ */
1420
+ function validateTask ( currentUser , challenge , data , challengeResources ) {
1421
+ if ( ! _ . get ( challenge , "legacy.pureV5Task" ) ) {
1422
+ // Not a Task
1423
+ return ;
1424
+ }
1425
+
1426
+ // Status changed to Active, indicating launch a Task
1427
+ const isLaunchTask =
1428
+ data . status === constants . challengeStatuses . Active &&
1429
+ challenge . status !== constants . challengeStatuses . Active ;
1430
+
1431
+ // Status changed to Completed, indicating complete a Task
1432
+ const isCompleteTask =
1433
+ data . status === constants . challengeStatuses . Completed &&
1434
+ challenge . status !== constants . challengeStatuses . Completed ;
1435
+
1436
+ // When complete a Task, input data should have winners
1437
+ if ( isCompleteTask && ( ! data . winners || ! data . winners . length ) ) {
1438
+ throw new errors . BadRequestError ( "The winners is required to complete a Task" ) ;
1439
+ }
1440
+
1441
+ if ( ! currentUser . isMachine && ( isLaunchTask || isCompleteTask ) ) {
1442
+ // Whether task is assigned to current user
1443
+ const assignedToCurrentUser =
1444
+ _ . filter (
1445
+ challengeResources ,
1446
+ ( r ) =>
1447
+ r . roleId === config . SUBMITTER_ROLE_ID &&
1448
+ _ . toString ( r . memberId ) === _ . toString ( currentUser . userId )
1449
+ ) . length > 0 ;
1450
+
1451
+ if ( assignedToCurrentUser ) {
1452
+ throw new errors . ForbiddenError (
1453
+ `You are not allowed to ${
1454
+ data . status === constants . challengeStatuses . Active ? "lanuch" : "complete"
1455
+ } task assigned to yourself. Please contact manager to operate.`
1456
+ ) ;
1457
+ }
1458
+ }
1459
+ }
1460
+
1413
1461
/**
1414
1462
* Update challenge.
1415
1463
* @param {Object } currentUser the user who perform operation
@@ -1441,7 +1489,10 @@ async function updateChallenge(currentUser, challengeId, data) {
1441
1489
data = sanitizeData ( sanitizeChallenge ( data ) , challenge ) ;
1442
1490
logger . debug ( `Sanitized Data: ${ JSON . stringify ( data ) } ` ) ;
1443
1491
1444
- await validateChallengeUpdateRequest ( currentUser , challenge , data ) ;
1492
+ const challengeResources = await helper . getChallengeResources ( challengeId ) ;
1493
+
1494
+ await validateChallengeUpdateRequest ( currentUser , challenge , data , challengeResources ) ;
1495
+ validateTask ( currentUser , challenge , data , challengeResources ) ;
1445
1496
1446
1497
let sendActivationEmail = false ;
1447
1498
let sendSubmittedEmail = false ;
@@ -1716,7 +1767,7 @@ async function updateChallenge(currentUser, challengeId, data) {
1716
1767
}
1717
1768
1718
1769
if ( data . winners && data . winners . length && data . winners . length > 0 ) {
1719
- await validateWinners ( data . winners , challengeId ) ;
1770
+ await validateWinners ( data . winners , challengeResources ) ;
1720
1771
}
1721
1772
1722
1773
// Only m2m tokens are allowed to modify the `task.*` information on a challenge
@@ -1777,7 +1828,6 @@ async function updateChallenge(currentUser, challengeId, data) {
1777
1828
1778
1829
if ( _ . get ( type , "isTask" ) ) {
1779
1830
if ( ! _ . isEmpty ( _ . get ( data , "task.memberId" ) ) ) {
1780
- const challengeResources = await helper . getChallengeResources ( challengeId ) ;
1781
1831
const registrants = _ . filter (
1782
1832
challengeResources ,
1783
1833
( r ) => r . roleId === config . SUBMITTER_ROLE_ID
0 commit comments