@@ -419,6 +419,33 @@ async function searchChallenges(currentUser, criteria) {
419419
420420 const _hasAdminRole = hasAdminRole ( currentUser ) ;
421421
422+ const normalizeGroupIdValue = ( value ) => {
423+ if ( _ . isNil ( value ) ) {
424+ return null ;
425+ }
426+ const normalized = _ . toString ( value ) . trim ( ) ;
427+ if ( ! normalized ) {
428+ return null ;
429+ }
430+ const lowered = normalized . toLowerCase ( ) ;
431+ if ( lowered === "null" || lowered === "undefined" ) {
432+ return null ;
433+ }
434+ return normalized ;
435+ } ;
436+
437+ const normalizeGroupIdList = ( list ) => {
438+ if ( _ . isNil ( list ) ) {
439+ return [ ] ;
440+ }
441+ const arrayValue = Array . isArray ( list ) ? list : [ list ] ;
442+ return _ . uniq (
443+ arrayValue
444+ . map ( ( value ) => normalizeGroupIdValue ( value ) )
445+ . filter ( ( value ) => ! _ . isNil ( value ) )
446+ ) ;
447+ } ;
448+
422449 let includedTrackIds = _ . isArray ( criteria . trackIds ) ? criteria . trackIds : [ ] ;
423450 let includedTypeIds = _ . isArray ( criteria . typeIds ) ? criteria . typeIds : [ ] ;
424451
@@ -745,52 +772,63 @@ async function searchChallenges(currentUser, criteria) {
745772
746773 let groupsToFilter = [ ] ;
747774 let accessibleGroups = [ ] ;
775+ let accessibleGroupsSet = new Set ( ) ;
748776
749777 if ( currentUser && ! currentUser . isMachine && ! _hasAdminRole ) {
750- accessibleGroups = await helper . getCompleteUserGroupTreeIds ( currentUser . userId ) ;
778+ const rawAccessibleGroups = await helper . getCompleteUserGroupTreeIds ( currentUser . userId ) ;
779+ accessibleGroups = normalizeGroupIdList ( rawAccessibleGroups ) ;
780+ accessibleGroupsSet = new Set ( accessibleGroups ) ;
751781 }
752782
753783 // Filter all groups from the criteria to make sure the user can access those
754784 if ( ! _ . isUndefined ( criteria . group ) || ! _ . isUndefined ( criteria . groups ) ) {
785+ const criteriaGroupsList = _ . isNil ( criteria . groups ) ? [ ] : [ ] . concat ( criteria . groups ) ;
786+
755787 // check group access
756788 if ( _ . isUndefined ( currentUser ) ) {
757- if ( criteria . group ) {
758- const group = await helper . getGroupById ( criteria . group ) ;
789+ const normalizedGroup = normalizeGroupIdValue ( criteria . group ) ;
790+ if ( normalizedGroup ) {
791+ const group = await helper . getGroupById ( normalizedGroup ) ;
759792 if ( group && ! group . privateGroup ) {
760- groupsToFilter . push ( criteria . group ) ;
793+ groupsToFilter . push ( normalizedGroup ) ;
761794 }
762795 }
763- if ( criteria . groups && criteria . groups . length > 0 ) {
764- const promises = [ ] ;
765- _ . each ( criteria . groups , ( g ) => {
766- promises . push (
767- ( async ( ) => {
768- const group = await helper . getGroupById ( g ) ;
769- if ( group && ! group . privateGroup ) {
770- groupsToFilter . push ( g ) ;
771- }
772- } ) ( )
773- ) ;
796+
797+ if ( criteriaGroupsList . length > 0 ) {
798+ const promises = criteriaGroupsList . map ( async ( groupValue ) => {
799+ const normalized = normalizeGroupIdValue ( groupValue ) ;
800+ if ( ! normalized ) {
801+ return ;
802+ }
803+ const group = await helper . getGroupById ( normalized ) ;
804+ if ( group && ! group . privateGroup ) {
805+ groupsToFilter . push ( normalized ) ;
806+ }
774807 } ) ;
775808 await Promise . all ( promises ) ;
776809 }
777810 } else if ( ! currentUser . isMachine && ! _hasAdminRole ) {
778- if ( accessibleGroups . includes ( criteria . group ) ) {
779- groupsToFilter . push ( criteria . group ) ;
811+ const normalizedGroup = normalizeGroupIdValue ( criteria . group ) ;
812+ if ( normalizedGroup && accessibleGroupsSet . has ( normalizedGroup ) ) {
813+ groupsToFilter . push ( normalizedGroup ) ;
780814 }
781- if ( criteria . groups && criteria . groups . length > 0 ) {
782- _ . each ( criteria . groups , ( g ) => {
783- if ( accessibleGroups . includes ( g ) ) {
784- groupsToFilter . push ( g ) ;
815+
816+ if ( criteriaGroupsList . length > 0 ) {
817+ criteriaGroupsList . forEach ( ( groupValue ) => {
818+ const normalized = normalizeGroupIdValue ( groupValue ) ;
819+ if ( normalized && accessibleGroupsSet . has ( normalized ) ) {
820+ groupsToFilter . push ( normalized ) ;
785821 }
786822 } ) ;
787823 }
788824 } else {
789- groupsToFilter = [ ...( criteria . groups ? criteria . groups : [ ] ) ] ;
790- if ( criteria . group ) {
791- groupsToFilter . push ( criteria . group ) ;
825+ groupsToFilter = normalizeGroupIdList ( criteriaGroupsList ) ;
826+ const normalizedGroup = normalizeGroupIdValue ( criteria . group ) ;
827+ if ( normalizedGroup ) {
828+ groupsToFilter . push ( normalizedGroup ) ;
792829 }
793830 }
831+
794832 groupsToFilter = _ . uniq ( groupsToFilter ) ;
795833
796834 if ( groupsToFilter . length === 0 ) {
@@ -2261,7 +2299,7 @@ async function updateChallenge(currentUser, challengeId, data) {
22612299 }
22622300
22632301 if ( ! _ . isUndefined ( data . terms ) ) {
2264- await helper . validateChallengeTerms ( data . terms ) ;
2302+ data . terms = await helper . validateChallengeTerms ( data . terms ) ;
22652303 }
22662304
22672305 if ( data . phases && data . phases . length > 0 ) {
@@ -2784,7 +2822,8 @@ function sanitizeChallenge(challenge) {
27842822 } ) ) ;
27852823 }
27862824 if ( challenge . terms ) {
2787- sanitized . terms = _ . map ( challenge . terms , ( term ) => _ . pick ( term , [ "id" , "roleId" ] ) ) ;
2825+ const uniqueTerms = helper . dedupeChallengeTerms ( challenge . terms || [ ] ) ;
2826+ sanitized . terms = _ . map ( uniqueTerms , ( term ) => _ . pick ( term , [ "id" , "roleId" ] ) ) ;
27882827 }
27892828 if ( challenge . attachments ) {
27902829 sanitized . attachments = _ . map ( challenge . attachments , ( attachment ) =>
0 commit comments