@@ -30,24 +30,57 @@ async function getGroupsService() {
30
30
return res ;
31
31
}
32
32
33
- const METADATA_PATH = path . resolve ( __dirname , '../tc-communities' ) ;
34
- const VALID_IDS = isomorphy . isServerSide ( )
35
- && fs . readdirSync ( METADATA_PATH ) . filter ( ( id ) => {
36
- /* Here we check which ids are correct, and also popuate SUBDOMAIN_COMMUNITY
37
- * map. */
38
- const uri = path . resolve ( METADATA_PATH , id , 'metadata.json' ) ;
33
+ const getValidIds = async ( METADATA_PATH ) => {
34
+ if ( ! isomorphy . isServerSide ( ) ) return [ ] ;
35
+ let VALID_IDS = [ ] ;
36
+
39
37
try {
40
- const meta = JSON . parse ( fs . readFileSync ( uri , 'utf8' ) ) ;
41
- if ( meta . subdomains ) {
42
- meta . subdomains . forEach ( ( subdomain ) => {
43
- SUBDOMAIN_COMMUNITY [ subdomain ] = id ;
44
- } ) ;
45
- }
46
- return true ;
47
- } catch ( e ) {
48
- return false ;
38
+ const ids = await fs . promises . readdir ( METADATA_PATH ) ;
39
+ const validationPromises = ids . map ( async ( id ) => {
40
+ const uri = path . resolve ( METADATA_PATH , id , 'metadata.json' ) ;
41
+
42
+ try {
43
+ // Check if the file exists
44
+ await fs . promises . access ( uri ) ;
45
+
46
+ // Get file stats
47
+ const stats = await fs . promises . stat ( uri ) ;
48
+ const MAX_FILE_SIZE = 1 * 1024 * 1024 ; // 1 MB
49
+ if ( stats . size > MAX_FILE_SIZE ) {
50
+ console . warn ( `Metadata file too large for ID: ${ id } ` ) ;
51
+ return null ; // Exclude invalid ID
52
+ }
53
+
54
+ // Parse and validate JSON
55
+ const meta = JSON . parse ( await fs . promises . readFile ( uri , 'utf8' ) ) ;
56
+
57
+ // Check if "subdomains" is a valid array
58
+ if ( Array . isArray ( meta . subdomains ) ) {
59
+ meta . subdomains . forEach ( ( subdomain ) => {
60
+ if ( typeof subdomain === 'string' ) {
61
+ SUBDOMAIN_COMMUNITY [ subdomain ] = id ;
62
+ } else {
63
+ console . warn ( `Invalid subdomain entry for ID: ${ id } ` ) ;
64
+ }
65
+ } ) ;
66
+ }
67
+
68
+ return id ;
69
+ } catch ( e ) {
70
+ console . error ( `Error processing metadata for ID: ${ id } ` , e . message ) ;
71
+ return null ;
72
+ }
73
+ } ) ;
74
+
75
+ const results = await Promise . all ( validationPromises ) ;
76
+ VALID_IDS = results . filter ( id => id !== null ) ;
77
+ } catch ( err ) {
78
+ console . error ( `Error reading metadata directory: ${ METADATA_PATH } ` , err . message ) ;
79
+ return [ ] ;
49
80
}
50
- } ) ;
81
+
82
+ return VALID_IDS ;
83
+ } ;
51
84
52
85
/**
53
86
* Given an array of group IDs, returns an array containing IDs of all those
@@ -140,10 +173,12 @@ getMetadata.maxage = 5 * 60 * 1000; // 5 min in ms.
140
173
* @return {Promise } Resolves to the array of community data objects. Each of
141
174
* the objects indludes only the most important data on the community.
142
175
*/
143
- export function getList ( userGroupIds ) {
176
+ export async function getList ( userGroupIds ) {
144
177
const list = [ ] ;
178
+ const METADATA_PATH = path . resolve ( __dirname , '../tc-communities' ) ;
179
+ const validIds = await getValidIds ( METADATA_PATH ) ;
145
180
return Promise . all (
146
- VALID_IDS . map ( id => getMetadata ( id ) . then ( ( data ) => {
181
+ validIds . map ( id => getMetadata ( id ) . then ( ( data ) => {
147
182
if ( ! data . authorizedGroupIds
148
183
|| _ . intersection ( data . authorizedGroupIds , userGroupIds ) . length ) {
149
184
list . push ( {
0 commit comments