const permissionResult = await this.checkPermissions( finalActionList.map((action: { id: string }) => action.id), userId, ACTION_PERMISSION.map(({ permission }) => permission) ); // Checking the permissions for a user against a list of actionIds and permissions async checkPermissions( actionIds: string[], userId: string, permissions: ActionsResourceFGAPermissions[] ): Promise> { const functionStartTime = Date.now(); const fgaRelationBuilderStartTime = Date.now(); const fgaRelationChecks = []; this.logger.debug( `[checkPermissions] Checking permissions: ${permissions.join(', ')} for user: ${userId}` ); for (const actionId of actionIds) { for (const permission of permissions) { fgaRelationChecks.push( this.ActionFGAHelper.generateUserFGARelationForPermissionCheck( actionId, userId, permission ) ); } } const fgaRelationBuilderDuration = Date.now() - fgaRelationBuilderStartTime; this.logger.debug( `[checkPermissions] Prepared ${fgaRelationChecks.length} relation checks for ${actionIds.length} actions (user: ${userId}) in ${fgaRelationBuilderDuration}ms` ); this.logger.debug( `[checkPermissions] FGA Relations: ${JSON.stringify(fgaRelationChecks.map(rel => ({ resource: rel.resource, relation: rel.relation, target: rel.target })), null, 2)}` ); const descopeCallStartTime = Date.now(); this.logger.debug('[checkPermissions] Calling Descope checkRelationFGA API'); const fgaRelationChecksResponse = await this.descopeService.checkRelationFGA(fgaRelationChecks); const descopeCallDuration = Date.now() - descopeCallStartTime; this.logger.debug( `[checkPermissions] Descope checkRelationFGA API completed in ${descopeCallDuration}ms (response size: ${fgaRelationChecksResponse.length} checks)` ); const mappingStartTime = Date.now(); const resultMap = fgaRelationChecksResponse.reduce((map, fgaRelationCheck) => { const actionId = fgaRelationCheck.tuple.resource; const relationship_key = fgaRelationCheck.tuple.relation; const allowed = fgaRelationCheck.allowed; if (!map.has(actionId)) { map.set(actionId, []); } map.get(actionId).push({ relationship_key, allowed, }); return map; }, new Map()); const mappingDuration = Date.now() - mappingStartTime; const functionEndTime = Date.now(); const totalDuration = functionEndTime - functionStartTime; this.logger.debug( `[checkPermissions] Function completed. Total duration: ${totalDuration}ms\n` + ` - FGA relation builder: ${fgaRelationBuilderDuration}ms\n` + ` - Descope API call: ${descopeCallDuration}ms\n` + ` - Result mapping: ${mappingDuration}ms\n` + ` - Results mapped to ${resultMap.size} actions` ); return resultMap; } // checking fga relations here public async checkRelationFGA( relations: IFGARelation[] ): Promise { await this.setupDescopeClient(); const response = await this.descopeClient.management.fga.check(relations); return response.data ?? []; }