@yrpri/api 9.0.103 → 9.0.105

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (422) hide show
  1. package/package.json +1 -2
  2. package/dist/active-citizen/controllers/activities.cjs +0 -174
  3. package/dist/active-citizen/controllers/news_feeds.cjs +0 -96
  4. package/dist/active-citizen/controllers/notifications.cjs +0 -243
  5. package/dist/active-citizen/controllers/recommendations.cjs +0 -280
  6. package/dist/active-citizen/engine/allOurIdeas/aiHelper.js +0 -204
  7. package/dist/active-citizen/engine/allOurIdeas/explainAnswersAssistant.js +0 -66
  8. package/dist/active-citizen/engine/allOurIdeas/iconGenerator.js +0 -38
  9. package/dist/active-citizen/engine/analytics/export_anon_community_activities.js +0 -334
  10. package/dist/active-citizen/engine/analytics/importer.js +0 -308
  11. package/dist/active-citizen/engine/analytics/manager.cjs +0 -377
  12. package/dist/active-citizen/engine/analytics/plausible/manager.cjs +0 -500
  13. package/dist/active-citizen/engine/analytics/statsCalc.cjs +0 -194
  14. package/dist/active-citizen/engine/analytics/utils.cjs +0 -369
  15. package/dist/active-citizen/engine/marketing/campaign.cjs +0 -90
  16. package/dist/active-citizen/engine/moderation/fraud/CreateFraudAuditReport.cjs +0 -313
  17. package/dist/active-citizen/engine/moderation/fraud/FraudBase.cjs +0 -239
  18. package/dist/active-citizen/engine/moderation/fraud/FraudDeleteBase.cjs +0 -211
  19. package/dist/active-citizen/engine/moderation/fraud/FraudDeleteEndorsements.cjs +0 -120
  20. package/dist/active-citizen/engine/moderation/fraud/FraudDeletePointQualities.cjs +0 -114
  21. package/dist/active-citizen/engine/moderation/fraud/FraudDeletePoints.cjs +0 -101
  22. package/dist/active-citizen/engine/moderation/fraud/FraudDeletePosts.cjs +0 -84
  23. package/dist/active-citizen/engine/moderation/fraud/FraudDeleteRatings.cjs +0 -15
  24. package/dist/active-citizen/engine/moderation/fraud/FraudGetBase.cjs +0 -133
  25. package/dist/active-citizen/engine/moderation/fraud/FraudGetEndorsements.cjs +0 -185
  26. package/dist/active-citizen/engine/moderation/fraud/FraudGetPointQualities.cjs +0 -184
  27. package/dist/active-citizen/engine/moderation/fraud/FraudGetPoints.cjs +0 -170
  28. package/dist/active-citizen/engine/moderation/fraud/FraudGetPosts.cjs +0 -109
  29. package/dist/active-citizen/engine/moderation/fraud/FraudGetRatings.cjs +0 -140
  30. package/dist/active-citizen/engine/moderation/fraud/FraudScannerNotifier.cjs +0 -279
  31. package/dist/active-citizen/engine/moderation/get_moderation_items.cjs +0 -386
  32. package/dist/active-citizen/engine/moderation/image_labeling/CommunityLabeling.cjs +0 -49
  33. package/dist/active-citizen/engine/moderation/image_labeling/GroupLabeling.cjs +0 -68
  34. package/dist/active-citizen/engine/moderation/image_labeling/ImageLabelingBase.cjs +0 -288
  35. package/dist/active-citizen/engine/moderation/image_labeling/PointLabeling.cjs +0 -33
  36. package/dist/active-citizen/engine/moderation/image_labeling/PostLabeling.cjs +0 -56
  37. package/dist/active-citizen/engine/moderation/perspective_api_client.cjs +0 -106
  38. package/dist/active-citizen/engine/moderation/process_moderation_items.cjs +0 -344
  39. package/dist/active-citizen/engine/moderation/toxicity_analysis.cjs +0 -810
  40. package/dist/active-citizen/engine/news_feeds/activity_and_item_index_definitions.cjs +0 -15
  41. package/dist/active-citizen/engine/news_feeds/generate_dynamically.cjs +0 -362
  42. package/dist/active-citizen/engine/news_feeds/generate_from_notifications.cjs +0 -268
  43. package/dist/active-citizen/engine/news_feeds/news_feeds_utils.cjs +0 -439
  44. package/dist/active-citizen/engine/notifications/emails_utils.cjs +0 -569
  45. package/dist/active-citizen/engine/notifications/generate_point_notifications.cjs +0 -233
  46. package/dist/active-citizen/engine/notifications/generate_post_notifications.cjs +0 -118
  47. package/dist/active-citizen/engine/notifications/generate_post_status_change_notifications.cjs +0 -41
  48. package/dist/active-citizen/engine/notifications/notifications_utils.cjs +0 -148
  49. package/dist/active-citizen/engine/notifications/point_delivery.cjs +0 -54
  50. package/dist/active-citizen/engine/notifications/post_delivery.cjs +0 -31
  51. package/dist/active-citizen/engine/notifications/process_delayed_notifications.cjs +0 -471
  52. package/dist/active-citizen/engine/notifications/process_general_notifications.cjs +0 -212
  53. package/dist/active-citizen/engine/old/exporters/categories_dataset.js +0 -153
  54. package/dist/active-citizen/engine/old/exporters/dataset_tools.js +0 -80
  55. package/dist/active-citizen/engine/old/exporters/sentiment_dataset.js +0 -157
  56. package/dist/active-citizen/engine/recommendations/events_importer.cjs +0 -139
  57. package/dist/active-citizen/engine/recommendations/events_manager.cjs +0 -212
  58. package/dist/active-citizen/engine/reports/add_points_to_sheet.cjs +0 -83
  59. package/dist/active-citizen/engine/reports/commonUtils.js +0 -75
  60. package/dist/active-citizen/engine/reports/common_utils.cjs +0 -740
  61. package/dist/active-citizen/engine/reports/docx_group_report.cjs +0 -596
  62. package/dist/active-citizen/engine/reports/xlsAllOurIdeasExport.js +0 -232
  63. package/dist/active-citizen/engine/reports/xls_community_users_report.cjs +0 -277
  64. package/dist/active-citizen/engine/reports/xls_group_report.cjs +0 -718
  65. package/dist/active-citizen/llms/baseChatBot.js +0 -183
  66. package/dist/active-citizen/llms/imageGeneration/chatGptImageGenerator.js +0 -56
  67. package/dist/active-citizen/llms/imageGeneration/collectionImageGenerator.js +0 -109
  68. package/dist/active-citizen/llms/imageGeneration/dalleImageGenerator.js +0 -84
  69. package/dist/active-citizen/llms/imageGeneration/fluxImageGenerator.js +0 -49
  70. package/dist/active-citizen/llms/imageGeneration/iImageGenerator.js +0 -1
  71. package/dist/active-citizen/llms/imageGeneration/imageProcessorService.js +0 -64
  72. package/dist/active-citizen/llms/imageGeneration/imagenImageGenerator.js +0 -107
  73. package/dist/active-citizen/llms/imageGeneration/s3Service.js +0 -110
  74. package/dist/active-citizen/llms/llmTranslation.js +0 -472
  75. package/dist/active-citizen/models/ac_activity.cjs +0 -216
  76. package/dist/active-citizen/models/ac_background_job.cjs +0 -109
  77. package/dist/active-citizen/models/ac_campaign.cjs +0 -97
  78. package/dist/active-citizen/models/ac_client_activity.cjs +0 -23
  79. package/dist/active-citizen/models/ac_delayed_notification.cjs +0 -43
  80. package/dist/active-citizen/models/ac_following.cjs +0 -43
  81. package/dist/active-citizen/models/ac_list.cjs +0 -68
  82. package/dist/active-citizen/models/ac_list_users.cjs +0 -19
  83. package/dist/active-citizen/models/ac_mute.cjs +0 -27
  84. package/dist/active-citizen/models/ac_news_feed_item.cjs +0 -57
  85. package/dist/active-citizen/models/ac_news_feed_processed_range.cjs +0 -59
  86. package/dist/active-citizen/models/ac_notification.cjs +0 -292
  87. package/dist/active-citizen/models/ac_translation_cache.cjs +0 -750
  88. package/dist/active-citizen/models/ac_watching.cjs +0 -31
  89. package/dist/active-citizen/scripts/analytics/setup_all_plausible_goals.cjs +0 -13
  90. package/dist/active-citizen/scripts/fix_old_delayed_notifications.js +0 -63
  91. package/dist/active-citizen/scripts/kue_status.js +0 -31
  92. package/dist/active-citizen/scripts/kue_watch_stuck_jobs.js +0 -24
  93. package/dist/active-citizen/scripts/translation_clear_language.js +0 -117
  94. package/dist/active-citizen/scripts/translation_delete.js +0 -27
  95. package/dist/active-citizen/scripts/translation_replace_text_from_url.js +0 -180
  96. package/dist/active-citizen/scripts/translation_update.js +0 -28
  97. package/dist/active-citizen/scripts/translations_list.js +0 -27
  98. package/dist/active-citizen/utils/airbrake.cjs +0 -17
  99. package/dist/active-citizen/utils/get_anonymous_system_user.cjs +0 -21
  100. package/dist/active-citizen/utils/i18n.cjs +0 -3
  101. package/dist/active-citizen/utils/logger.cjs +0 -25
  102. package/dist/active-citizen/utils/redisConnection.cjs +0 -29
  103. package/dist/active-citizen/utils/to_json.cjs +0 -9
  104. package/dist/active-citizen/utils/translation_cloning.cjs +0 -171
  105. package/dist/active-citizen/utils/translation_helpers.cjs +0 -534
  106. package/dist/active-citizen/utils/truncate_text.cjs +0 -21
  107. package/dist/active-citizen/utils/updateAllLocalesFromEn.js +0 -253
  108. package/dist/active-citizen/utils/updateLocaleFolders.js +0 -34
  109. package/dist/active-citizen/workers/activity.cjs +0 -189
  110. package/dist/active-citizen/workers/anonymizations.cjs +0 -734
  111. package/dist/active-citizen/workers/bulk_status_update.cjs +0 -458
  112. package/dist/active-citizen/workers/delayed_jobs.cjs +0 -244
  113. package/dist/active-citizen/workers/deletions.cjs +0 -1911
  114. package/dist/active-citizen/workers/email.cjs +0 -9
  115. package/dist/active-citizen/workers/fraud_management.cjs +0 -109
  116. package/dist/active-citizen/workers/generativeAi.js +0 -56
  117. package/dist/active-citizen/workers/main.cjs +0 -89
  118. package/dist/active-citizen/workers/marketing.cjs +0 -25
  119. package/dist/active-citizen/workers/moderation.cjs +0 -73
  120. package/dist/active-citizen/workers/notification_delivery.cjs +0 -368
  121. package/dist/active-citizen/workers/notification_news_feed.cjs +0 -142
  122. package/dist/active-citizen/workers/queue.cjs +0 -99
  123. package/dist/active-citizen/workers/recount.cjs +0 -74
  124. package/dist/active-citizen/workers/reports.cjs +0 -42
  125. package/dist/active-citizen/workers/similarities.cjs +0 -21
  126. package/dist/active-citizen/workers/speech_to_text.cjs +0 -482
  127. package/dist/agents/assistants/agentAssistant.js +0 -88
  128. package/dist/agents/assistants/baseAssistant.js +0 -888
  129. package/dist/agents/assistants/baseAssistantWithVoice.js +0 -150
  130. package/dist/agents/assistants/modes/agentDirectConnection.js +0 -84
  131. package/dist/agents/assistants/modes/agentSelectionMode.js +0 -44
  132. package/dist/agents/assistants/modes/baseAssistantMode.js +0 -54
  133. package/dist/agents/assistants/modes/tools/agentTools.js +0 -447
  134. package/dist/agents/assistants/modes/tools/baseTools.js +0 -58
  135. package/dist/agents/assistants/modes/tools/loginTools.js +0 -156
  136. package/dist/agents/assistants/modes/tools/models/agents.js +0 -146
  137. package/dist/agents/assistants/modes/tools/models/subscriptions.js +0 -332
  138. package/dist/agents/assistants/modes/tools/models/users.js +0 -11
  139. package/dist/agents/assistants/modes/tools/navigationTools.js +0 -166
  140. package/dist/agents/assistants/modes/tools/subscriptionTools.js +0 -323
  141. package/dist/agents/assistants/modes/tools/workflowConverstationTools.js +0 -112
  142. package/dist/agents/assistants/voiceAssistant.js +0 -619
  143. package/dist/agents/controllers/agentProductController.js +0 -103
  144. package/dist/agents/controllers/agentSubscriptionController.js +0 -261
  145. package/dist/agents/controllers/assistantsController.js +0 -511
  146. package/dist/agents/controllers/policySynthAgents.js +0 -395
  147. package/dist/agents/managers/agentProductManager.js +0 -91
  148. package/dist/agents/managers/emailInvitesManager.js +0 -55
  149. package/dist/agents/managers/emailTemplateRenderer.js +0 -362
  150. package/dist/agents/managers/newAiModelSetup.js +0 -650
  151. package/dist/agents/managers/notificationAgentQueueManager.js +0 -510
  152. package/dist/agents/managers/subscriptionManager.js +0 -535
  153. package/dist/agents/managers/workflowConversationManager.js +0 -79
  154. package/dist/agents/models/agentProduct.js +0 -116
  155. package/dist/agents/models/agentProductBoosterPurchase.js +0 -58
  156. package/dist/agents/models/agentProductBundle.js +0 -68
  157. package/dist/agents/models/agentProductRun.js +0 -52
  158. package/dist/agents/models/discount.js +0 -88
  159. package/dist/agents/models/subscription.js +0 -79
  160. package/dist/agents/models/subscriptionPlan.js +0 -46
  161. package/dist/agents/models/subscriptionUser.js +0 -27
  162. package/dist/agents/models/testData/createEvolyAgentProduct.js +0 -477
  163. package/dist/agents/models/testData/old/updateAgentWorkflowConfiguration.js +0 -230
  164. package/dist/agents/models/testData/setupEvolyAgentProductConfig.js +0 -233
  165. package/dist/agents/models/testData/updateAgentWorkflowConfiguration.js +0 -230
  166. package/dist/agents/models/workflowConversation.js +0 -53
  167. package/dist/agents/tools/setTemplateWorkflowCommunityId.js +0 -46
  168. package/dist/app.js +0 -943
  169. package/dist/authorization.cjs +0 -1860
  170. package/dist/bot_control.js +0 -1930
  171. package/dist/config/config.cjs +0 -14
  172. package/dist/config/config.js +0 -14
  173. package/dist/controllers/allOurIdeas.js +0 -696
  174. package/dist/controllers/audios.cjs +0 -100
  175. package/dist/controllers/bulkStatusUpdates.cjs +0 -202
  176. package/dist/controllers/categories.cjs +0 -199
  177. package/dist/controllers/communities.cjs +0 -2996
  178. package/dist/controllers/domains.cjs +0 -1341
  179. package/dist/controllers/externalIds.cjs +0 -223
  180. package/dist/controllers/groups.cjs +0 -4309
  181. package/dist/controllers/images.cjs +0 -499
  182. package/dist/controllers/index.cjs +0 -449
  183. package/dist/controllers/legacyPages.cjs +0 -35
  184. package/dist/controllers/legacyPosts.cjs +0 -56
  185. package/dist/controllers/legacyUsers.cjs +0 -36
  186. package/dist/controllers/nonSpa.cjs +0 -574
  187. package/dist/controllers/organizations.cjs +0 -250
  188. package/dist/controllers/points.cjs +0 -1137
  189. package/dist/controllers/posts.cjs +0 -2036
  190. package/dist/controllers/ratings.cjs +0 -234
  191. package/dist/controllers/users.cjs +0 -2255
  192. package/dist/controllers/videos.cjs +0 -226
  193. package/dist/deleteUnwantedDeclerations.cjs +0 -55
  194. package/dist/migrations/agentAuditLogs.cjs +0 -46
  195. package/dist/migrations/agentClasses.cjs +0 -60
  196. package/dist/migrations/agentConnectorClasses.cjs +0 -61
  197. package/dist/migrations/agentConnectors.cjs +0 -50
  198. package/dist/migrations/agentEvals.cjs +0 -45
  199. package/dist/migrations/agentRegistries.cjs +0 -40
  200. package/dist/migrations/agents.cjs +0 -54
  201. package/dist/migrations/aiModels.cjs +0 -49
  202. package/dist/migrations/apiUsage.cjs +0 -47
  203. package/dist/migrations/apis.cjs +0 -49
  204. package/dist/migrations/groupPrivateData.cjs +0 -30
  205. package/dist/migrations/modelUsage.cjs +0 -60
  206. package/dist/migrations/oldMigrations/2019/20181030020612-AddActivitiesIndex.js +0 -23
  207. package/dist/migrations/oldMigrations/2019/20181102210612-AddFirstVideoFeatures.js +0 -360
  208. package/dist/migrations/oldMigrations/2019/20181212210612-ModerationFeatures.js +0 -29
  209. package/dist/migrations/oldMigrations/2019/2019010610612-CommunityFolders.js +0 -43
  210. package/dist/migrations/oldMigrations/2019/20190117020612-AddMissingIndexes.js +0 -24
  211. package/dist/migrations/oldMigrations/2019/20190117020612-RemoveUnusedIndexes.js +0 -29
  212. package/dist/migrations/oldMigrations/2019/20190127020612-RemoveUnusedIndexesPartThree.js +0 -22
  213. package/dist/migrations/oldMigrations/2019/20190127020612-RemoveUnusedIndexesPartTwo.js +0 -23
  214. package/dist/migrations/oldMigrations/2019/20190223020612-AddPrivateProfileDataToUsers.js +0 -18
  215. package/dist/migrations/oldMigrations/2019/20190706210612-AddCustomRatings.js +0 -43
  216. package/dist/migrations/oldMigrations/2019/20190829210612-AddGeneralStore.js +0 -36
  217. package/dist/migrations/oldMigrations/2019/20192811210612-AddAcClientActivities.js +0 -41
  218. package/dist/migrations/oldMigrations/2020/20190527020612-WorkOnIndexes.js +0 -88
  219. package/dist/migrations/oldMigrations/2020/20200409020612-AddBackgroundJob.js +0 -33
  220. package/dist/migrations/oldMigrations/2020/20200716210612-AddDataToCollections.js +0 -38
  221. package/dist/migrations/oldMigrations/2022/20220215100612-AddDataToEndorsements.js +0 -19
  222. package/dist/migrations/oldMigrations/2022/20220220100612-AddDataForFraudDetection.js +0 -19
  223. package/dist/migrations/oldMigrations/2022/20220903100612-AddPromotionFeatures.js +0 -127
  224. package/dist/migrations/oldMigrations/2022/onHold/20200527020612-AddCampaigns.js +0 -68
  225. package/dist/migrations/oldMigrations/2024/20241304175112-AddMediaSupportForHtmlGroups.cjs +0 -63
  226. package/dist/migrations/oldMigrations/older/20160511172514-AddNotificationFeatures.js +0 -14
  227. package/dist/migrations/oldMigrations/older/20161030020612-AddBulkStatusUpdate.js +0 -71
  228. package/dist/migrations/oldMigrations/older/20170514035258-add-metadata-to-invites.js +0 -12
  229. package/dist/migrations/oldMigrations/older/20180216020612-AddTranslationCaches.js +0 -46
  230. package/dist/migrations/oldMigrations/older/20180218210612-AddTranslationAndLanguages.js +0 -46
  231. package/dist/migrations/privateAccessStore.cjs +0 -55
  232. package/dist/migrations/zzz_associations.cjs +0 -154
  233. package/dist/migrations/zzzz_createUsersAndAdminsForClasses.cjs +0 -100
  234. package/dist/migrations/zzzzz_create_agent_runs.cjs +0 -606
  235. package/dist/migrations/zzzzzz_create_agent_runs_fix.cjs +0 -11
  236. package/dist/migrations/zzzzzzz_create_trees.cjs +0 -81
  237. package/dist/models/audio.cjs +0 -430
  238. package/dist/models/bulk_status_update.cjs +0 -58
  239. package/dist/models/campaign.cjs +0 -78
  240. package/dist/models/category.cjs +0 -94
  241. package/dist/models/community.cjs +0 -337
  242. package/dist/models/domain.cjs +0 -486
  243. package/dist/models/endorsement.cjs +0 -39
  244. package/dist/models/general_data_store.cjs +0 -20
  245. package/dist/models/group.cjs +0 -728
  246. package/dist/models/image.cjs +0 -579
  247. package/dist/models/index.cjs +0 -186
  248. package/dist/models/invite.cjs +0 -48
  249. package/dist/models/iso_country.cjs +0 -16
  250. package/dist/models/organization.cjs +0 -122
  251. package/dist/models/page.cjs +0 -273
  252. package/dist/models/point.cjs +0 -622
  253. package/dist/models/point_quality.cjs +0 -39
  254. package/dist/models/point_revision.cjs +0 -47
  255. package/dist/models/post.cjs +0 -680
  256. package/dist/models/post_revision.cjs +0 -38
  257. package/dist/models/post_status_change.cjs +0 -35
  258. package/dist/models/promotion.cjs +0 -34
  259. package/dist/models/rating.cjs +0 -51
  260. package/dist/models/relationship.cjs +0 -19
  261. package/dist/models/request_to_join.cjs +0 -20
  262. package/dist/models/user.cjs +0 -604
  263. package/dist/models/user_legacy_password.cjs +0 -13
  264. package/dist/models/video.cjs +0 -1137
  265. package/dist/publish.js +0 -40
  266. package/dist/repack.js +0 -53
  267. package/dist/scripts/addRatingUsersToGroup.js +0 -51
  268. package/dist/scripts/addUserToOrganization.js +0 -71
  269. package/dist/scripts/analyseRatingsForCommunity.js +0 -150
  270. package/dist/scripts/analyzeAndFixBrokenPointUsers.js +0 -28
  271. package/dist/scripts/analyzeEndorsementsByCountry.js +0 -70
  272. package/dist/scripts/analyzePostsForCommunity.js +0 -185
  273. package/dist/scripts/bulkStatusUpdates/listUpdates.js +0 -14
  274. package/dist/scripts/bulkStatusUpdates/mergeLatestPostsToUpdate.js +0 -110
  275. package/dist/scripts/bulkStatusUpdates/performUpdate.js +0 -116
  276. package/dist/scripts/bulkStatusUpdates/performUpdateForGroup.cjs +0 -124
  277. package/dist/scripts/bulkStatusUpdates/performUpdateForStatus.js +0 -141
  278. package/dist/scripts/change/changeVideoAspectTo.js +0 -34
  279. package/dist/scripts/change/setUseNewVersion.cjs +0 -22
  280. package/dist/scripts/changeCommunityGroupcount.js +0 -30
  281. package/dist/scripts/changeCommunityPostCount.js +0 -30
  282. package/dist/scripts/changeGroupPostCount.js +0 -30
  283. package/dist/scripts/changeLanguage.js +0 -50
  284. package/dist/scripts/changeOfficalStatus.js +0 -30
  285. package/dist/scripts/cleanups/deleteAnonNotifications.cjs +0 -91
  286. package/dist/scripts/cleanups/deleteLinkGroupsWithDeletedCommunities.js +0 -62
  287. package/dist/scripts/cleanups/deleteYearOldNotifications.cjs +0 -72
  288. package/dist/scripts/cleanups/removeAllUsersFromHiddenPublicGroup.js +0 -43
  289. package/dist/scripts/clearAllEndorsementInGroup.js +0 -50
  290. package/dist/scripts/cloning/clearUsersForCommunitiesFromUrl.js +0 -129
  291. package/dist/scripts/cloning/cloneFromUrlScript.js +0 -65
  292. package/dist/scripts/cloning/cloneWBFromUrlScriptAndCreateLinks.js +0 -140
  293. package/dist/scripts/cloning/cloneWBFromUrlScriptNoUsersOrPoints.js +0 -140
  294. package/dist/scripts/cloning/cloneWBSerbianFromUrlScriptAndCreateLinks.js +0 -131
  295. package/dist/scripts/cloning/copyCommunityConfigAndTranslationsFromURL.js +0 -173
  296. package/dist/scripts/cloning/copyCommunityOneGroupToDomainNoUsersNoEndorsements.js +0 -18
  297. package/dist/scripts/cloning/copyCommunityToDomainNoUsersNoEndorsements.js +0 -17
  298. package/dist/scripts/cloning/copyCommunityToDomainWithEverything.js +0 -17
  299. package/dist/scripts/cloning/copyCommunityToDomainWithOnlyGroups.js +0 -26
  300. package/dist/scripts/cloning/copyGroupConfigAndTranslationsFromURL.js +0 -205
  301. package/dist/scripts/cloning/copyPostToGroupOld.js +0 -397
  302. package/dist/scripts/cloning/copyPostVideosFromURL.js +0 -236
  303. package/dist/scripts/cloning/copyPostWithOutAnyVotingOrActivities.js +0 -17
  304. package/dist/scripts/cloning/deepCloneSerbianWBFromUrlScriptAndCreateLinks.js +0 -131
  305. package/dist/scripts/cloning/deepCloneWBFromUrlScriptAndCreateLinks.js +0 -139
  306. package/dist/scripts/cloning/setAdminsFromURL.js +0 -161
  307. package/dist/scripts/cloning/setExternalIdsFromURL.js +0 -129
  308. package/dist/scripts/countCommunity.js +0 -291
  309. package/dist/scripts/countCommunityUsers.js +0 -152
  310. package/dist/scripts/countDelayedNotifications.js +0 -18
  311. package/dist/scripts/countGroup.js +0 -246
  312. package/dist/scripts/countStuff.js +0 -67
  313. package/dist/scripts/countUniqueVotersInAGroup.js +0 -48
  314. package/dist/scripts/createInvitesAndShow.js +0 -75
  315. package/dist/scripts/database/sync_database.js +0 -14
  316. package/dist/scripts/database/sync_dev_database.js +0 -17
  317. package/dist/scripts/debugNotifications.js +0 -58
  318. package/dist/scripts/deleteAllNewsFeeds.js +0 -10
  319. package/dist/scripts/deleteCategory.js +0 -13
  320. package/dist/scripts/deleteOldAppActivities.js +0 -40
  321. package/dist/scripts/deletePostContactDataForCommunity.js +0 -53
  322. package/dist/scripts/destroy/destroy_all_but_one_domain.js +0 -1026
  323. package/dist/scripts/displayAuthorForPost.js +0 -16
  324. package/dist/scripts/endorsementFraudDetection/analyseEndorsementsForCommunity.js +0 -183
  325. package/dist/scripts/endorsementFraudDetection/bulkDeleteDuplicateEndorsmentsFromUrl.js +0 -208
  326. package/dist/scripts/exportAllStatusChanges.js +0 -36
  327. package/dist/scripts/exportClientAcitivity.js +0 -36
  328. package/dist/scripts/exportEndorsementsForCommunity.js +0 -79
  329. package/dist/scripts/exportPointQualitiesForCommunity.js +0 -84
  330. package/dist/scripts/exportPostsAndPointsForCommunity.js +0 -147
  331. package/dist/scripts/exportPostsDataSetForDomain.js +0 -244
  332. package/dist/scripts/exportPostsForGroup.js +0 -173
  333. package/dist/scripts/exportRatingsForPost.js +0 -15
  334. package/dist/scripts/exportUserEndorsementsWithUserAnalysis.js +0 -123
  335. package/dist/scripts/exportUsersForCommunity.js +0 -24
  336. package/dist/scripts/exportUsersForDomain.js +0 -24
  337. package/dist/scripts/exportUsersForGroup.js +0 -24
  338. package/dist/scripts/exports/ratingDistribution.js +0 -71
  339. package/dist/scripts/exports/whoEndorsedWhatByCommunity.js +0 -56
  340. package/dist/scripts/findUnusedClientImports.js +0 -56
  341. package/dist/scripts/fixAllPostPointCounts.js +0 -22
  342. package/dist/scripts/fixAnonNotificationsSettings.js +0 -48
  343. package/dist/scripts/fixCountKopavogur.js +0 -9
  344. package/dist/scripts/fixEndorsementsAfterCopyPostToGroup.js +0 -190
  345. package/dist/scripts/fixExternalUserId.js +0 -24
  346. package/dist/scripts/fixGroupAccess.js +0 -16
  347. package/dist/scripts/fixGroupIdeasAndPointsCount.js +0 -49
  348. package/dist/scripts/fixNotificationSettings.js +0 -39
  349. package/dist/scripts/fixSurveyRadioBakedInSubCodes.js +0 -64
  350. package/dist/scripts/fixWrongUserIdForStatusUpdates.js +0 -49
  351. package/dist/scripts/gallery/exportGalleryData.js +0 -40
  352. package/dist/scripts/gallery/importGalleryForCommunity.js +0 -168
  353. package/dist/scripts/gallery/readJsonAndDownloadImagesVersion2.js +0 -55
  354. package/dist/scripts/gallery/refreshAcApiPostIdsForCommunity.js +0 -58
  355. package/dist/scripts/genderAnalysis.js +0 -63
  356. package/dist/scripts/genderAnalysisByStatus.js +0 -62
  357. package/dist/scripts/importAllLocalesFromLocalFolders.js +0 -55
  358. package/dist/scripts/importDomain.js +0 -1652
  359. package/dist/scripts/keys/addOidcToDomain.cjs +0 -61
  360. package/dist/scripts/landUseGame/export3Ddata.js +0 -162
  361. package/dist/scripts/listLanguagesForGroup.js +0 -54
  362. package/dist/scripts/loadTestCreateDummyContentForGroup.js +0 -27
  363. package/dist/scripts/makeRecursiveMapData.js +0 -103
  364. package/dist/scripts/mapping/community_map_csv.js +0 -145
  365. package/dist/scripts/moveCommunityToDomain.js +0 -22
  366. package/dist/scripts/moveGroupToCommunity.js +0 -23
  367. package/dist/scripts/movePostToGroup.js +0 -101
  368. package/dist/scripts/movePostsToGroupsRecountGroupFromUrl.js +0 -297
  369. package/dist/scripts/oldMovePostToGroup.js +0 -153
  370. package/dist/scripts/processCsvForPdfUrls.js +0 -37
  371. package/dist/scripts/processCsvForTranslationAndToxicity.js +0 -125
  372. package/dist/scripts/recount/recount_recursive_communities.js +0 -125
  373. package/dist/scripts/recountALLCommunityGroupCounts.js +0 -37
  374. package/dist/scripts/recountAll.js +0 -97
  375. package/dist/scripts/recountCommunitesFromUrl.js +0 -58
  376. package/dist/scripts/recountCommunity.js +0 -19
  377. package/dist/scripts/recountGroup.js +0 -218
  378. package/dist/scripts/recountGroupNoUserChange.js +0 -219
  379. package/dist/scripts/resetAllEndorsementsForGroup.js +0 -57
  380. package/dist/scripts/resetEnTranslationForGroup.js +0 -45
  381. package/dist/scripts/setAdminOnAll.cjs +0 -107
  382. package/dist/scripts/setDomainAdmin.cjs +0 -43
  383. package/dist/scripts/setDomainLocales.js +0 -33
  384. package/dist/scripts/setEarlQuestionIdOnGroup.cjs +0 -29
  385. package/dist/scripts/setLanguageOnGroupCommunitesFromUrl.js +0 -86
  386. package/dist/scripts/setMemberOfAll.js +0 -101
  387. package/dist/scripts/setNewUserForContentOfCommunity.js +0 -189
  388. package/dist/scripts/setOfficialStatusOnAllPostsForCommunity.js +0 -35
  389. package/dist/scripts/setUserOnAll.js +0 -101
  390. package/dist/scripts/showCategoryForGroup.js +0 -18
  391. package/dist/scripts/showOldActivityTypes.js +0 -14
  392. package/dist/scripts/showPostsMissingCategoryForGroup.js +0 -17
  393. package/dist/scripts/showStatuses.js +0 -17
  394. package/dist/scripts/showUniqueVotersInCommunity.js +0 -61
  395. package/dist/scripts/showUserAgentsAndIpsForEmails.js +0 -66
  396. package/dist/scripts/simpleExportForGroupsForCommunity.js +0 -46
  397. package/dist/scripts/simpleExportForPointsForCommunity.js +0 -82
  398. package/dist/scripts/simpleExportForPostsForCommunity.js +0 -61
  399. package/dist/scripts/testForEndorsments.js +0 -21
  400. package/dist/scripts/undeleteGroupAndAllContent.js +0 -151
  401. package/dist/scripts/undeletePost.js +0 -135
  402. package/dist/scripts/unlinkSsn.js +0 -23
  403. package/dist/scripts/updateFromAlthingi.js +0 -303
  404. package/dist/server.js +0 -3
  405. package/dist/utils/airbrake.cjs +0 -17
  406. package/dist/utils/cjsCodeReview.js +0 -99
  407. package/dist/utils/community_mapping_tools.cjs +0 -124
  408. package/dist/utils/copy_utils.cjs +0 -1399
  409. package/dist/utils/docx_utils.cjs +0 -464
  410. package/dist/utils/export_utils.cjs +0 -491
  411. package/dist/utils/i18n.cjs +0 -17
  412. package/dist/utils/is_valid_db_id.cjs +0 -28
  413. package/dist/utils/logger.cjs +0 -25
  414. package/dist/utils/loggerTs.js +0 -26
  415. package/dist/utils/manifest_generator.cjs +0 -104
  416. package/dist/utils/parse_domain.cjs +0 -16
  417. package/dist/utils/recount_utils.cjs +0 -415
  418. package/dist/utils/sharing_parameters.cjs +0 -111
  419. package/dist/utils/sitemap_generator.cjs +0 -286
  420. package/dist/utils/to_json.cjs +0 -14
  421. package/dist/utils/ypLanguages.js +0 -747
  422. package/dist/webSockets.js +0 -77
@@ -1,4309 +0,0 @@
1
- "use strict";
2
- var express = require("express");
3
- var router = express.Router();
4
- var models = require("../models/index.cjs");
5
- var auth = require("../authorization.cjs");
6
- var log = require("../utils/logger.cjs");
7
- var toJson = require("../utils/to_json.cjs");
8
- var _ = require("lodash");
9
- var async = require("async");
10
- var crypto = require("crypto");
11
- var seededShuffle = require("knuth-shuffle-seeded");
12
- var multer = require("multer");
13
- var s3multer = require("multer-s3");
14
- var aws = require("aws-sdk");
15
- var getExportFileDataForGroup = require("../utils/export_utils.cjs").getExportFileDataForGroup;
16
- const exportGroupToDocx = require("../utils/docx_utils.cjs").exportGroupToDocx;
17
- const { v4: uuidv4 } = require("uuid");
18
- const { Op, literal } = require("sequelize");
19
- var moment = require("moment");
20
- var sanitizeFilename = require("sanitize-filename");
21
- var queue = require("../active-citizen/workers/queue.cjs");
22
- const getAllModeratedItemsByGroup = require("../active-citizen/engine/moderation/get_moderation_items.cjs").getAllModeratedItemsByGroup;
23
- const performSingleModerationAction = require("../active-citizen/engine/moderation/process_moderation_items.cjs").performSingleModerationAction;
24
- const request = require("request");
25
- const { updateAnswerTranslation, } = require("../active-citizen/utils/translation_helpers.cjs");
26
- const { updateSurveyTranslation, } = require("../active-citizen/utils/translation_helpers.cjs");
27
- const { plausibleStatsProxy, getPlausibleStats, } = require("../active-citizen/engine/analytics/plausible/manager.cjs");
28
- const { countAllModeratedItemsByGroup, } = require("../active-citizen/engine/moderation/get_moderation_items.cjs");
29
- const { isValidDbId } = require("../utils/is_valid_db_id.cjs");
30
- const { Sequelize } = require("sequelize");
31
- const getFromAnalyticsApi = require("../active-citizen/engine/analytics/manager.cjs").getFromAnalyticsApi;
32
- const triggerSimilaritiesTraining = require("../active-citizen/engine/analytics/manager.cjs").triggerSimilaritiesTraining;
33
- const sendBackAnalyticsResultsOrError = require("../active-citizen/engine/analytics/manager.cjs").sendBackAnalyticsResultsOrError;
34
- const countModelRowsByTimePeriod = require("../active-citizen/engine/analytics/statsCalc.cjs").countModelRowsByTimePeriod;
35
- const getGroupIncludes = require("../active-citizen/engine/analytics/statsCalc.cjs").getGroupIncludes;
36
- const getPointGroupIncludes = require("../active-citizen/engine/analytics/statsCalc.cjs").getPointGroupIncludes;
37
- const getParsedSimilaritiesContent = require("../active-citizen/engine/analytics/manager.cjs").getParsedSimilaritiesContent;
38
- const getTranslatedTextsForGroup = require("../active-citizen/utils/translation_helpers.cjs").getTranslatedTextsForGroup;
39
- const updateTranslationForGroup = require("../active-citizen/utils/translation_helpers.cjs").updateTranslationForGroup;
40
- const convertDocxSurveyToJson = require("../active-citizen/engine/analytics/manager.cjs").convertDocxSurveyToJson;
41
- const copyGroup = require("../utils/copy_utils.cjs").copyGroup;
42
- var s3 = new aws.S3({
43
- secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
44
- accessKeyId: process.env.AWS_ACCESS_KEY_ID,
45
- endpoint: process.env.S3_ENDPOINT || null,
46
- acl: "public-read",
47
- region: process.env.S3_REGION || (process.env.S3_ENDPOINT ? null : "us-east-1"),
48
- });
49
- var sendGroupOrError = function (res, group, context, user, error, errorStatus) {
50
- if (error || !group) {
51
- if (errorStatus === 404 ||
52
- (error &&
53
- error.message &&
54
- error.message.indexOf("invalid input syntax for type integer") > -1)) {
55
- log.warn("Group Not Found", {
56
- context: context,
57
- group: toJson(group),
58
- user: toJson(user),
59
- err: error,
60
- errorStatus: 404,
61
- });
62
- errorStatus = 404;
63
- }
64
- else {
65
- log.error("Group Error", {
66
- context: context,
67
- group: toJson(group),
68
- user: toJson(user),
69
- err: error,
70
- errorStatus: errorStatus ? errorStatus : 500,
71
- });
72
- }
73
- if (errorStatus) {
74
- res.sendStatus(errorStatus);
75
- }
76
- else {
77
- res.sendStatus(500);
78
- }
79
- }
80
- else {
81
- res.send(group);
82
- }
83
- };
84
- var getGroupAndUser = function (groupId, userId, userEmail, callback) {
85
- var user, group;
86
- async.series([
87
- function (seriesCallback) {
88
- models.Group.findOne({
89
- where: {
90
- id: groupId,
91
- },
92
- attributes: models.Group.defaultAttributesPublic,
93
- })
94
- .then(function (groupIn) {
95
- if (groupIn) {
96
- group = groupIn;
97
- }
98
- seriesCallback();
99
- })
100
- .catch(function (error) {
101
- seriesCallback(error);
102
- });
103
- },
104
- function (seriesCallback) {
105
- if (userId) {
106
- models.User.findOne({
107
- where: {
108
- id: userId,
109
- },
110
- attributes: ["id", "email", "name", "created_at"],
111
- })
112
- .then(function (userIn) {
113
- if (userIn) {
114
- user = userIn;
115
- }
116
- seriesCallback();
117
- })
118
- .catch(function (error) {
119
- seriesCallback(error);
120
- });
121
- }
122
- else {
123
- seriesCallback();
124
- }
125
- },
126
- function (seriesCallback) {
127
- if (userEmail) {
128
- models.User.findOne({
129
- where: {
130
- email: userEmail,
131
- },
132
- attributes: ["id", "email", "name", "created_at"],
133
- })
134
- .then(function (userIn) {
135
- if (userIn) {
136
- user = userIn;
137
- }
138
- seriesCallback();
139
- })
140
- .catch(function (error) {
141
- seriesCallback(error);
142
- });
143
- }
144
- else {
145
- seriesCallback();
146
- }
147
- },
148
- ], function (error) {
149
- if (error) {
150
- callback(error);
151
- }
152
- else {
153
- callback(null, group, user);
154
- }
155
- });
156
- };
157
- var truthValueFromBody = function (bodyParameter) {
158
- if (bodyParameter && bodyParameter != "") {
159
- return true;
160
- }
161
- else {
162
- return false;
163
- }
164
- };
165
- const moveGroupTo = (req, group) => {
166
- const splitMoveTo = req.body.moveGroupTo.split(" - ");
167
- const id = splitMoveTo[0];
168
- if (id && id.indexOf("C") > -1) {
169
- group.set("in_group_folder_id", null);
170
- }
171
- else if (!isNaN(id)) {
172
- if (parseInt(id) !== 0) {
173
- group.set("in_group_folder_id", parseInt(id));
174
- }
175
- }
176
- };
177
- var updateGroupConfigParameters = function (req, group) {
178
- if (!group.configuration) {
179
- group.set("configuration", {});
180
- }
181
- group.set("configuration.canVote", truthValueFromBody(req.body.canVote));
182
- group.set("configuration.canAddNewPosts", truthValueFromBody(req.body.canAddNewPosts));
183
- group.set("configuration.disableDebate", truthValueFromBody(req.body.disableDebate));
184
- group.set("configuration.locationHidden", truthValueFromBody(req.body.locationHidden));
185
- group.set("configuration.showWhoPostedPosts", truthValueFromBody(req.body.showWhoPostedPosts));
186
- group.set("configuration.allowAnonymousUsers", truthValueFromBody(req.body.allowAnonymousUsers));
187
- group.set("configuration.allowAnonymousAutoLogin", truthValueFromBody(req.body.allowAnonymousAutoLogin));
188
- group.set("configuration.anonymousAskRegistrationQuestions", truthValueFromBody(req.body.anonymousAskRegistrationQuestions));
189
- group.set("configuration.hideAllTabs", truthValueFromBody(req.body.hideAllTabs));
190
- group.set("configuration.hideNewPostOnPostPage", truthValueFromBody(req.body.hideNewPostOnPostPage));
191
- group.set("configuration.newPointOptional", truthValueFromBody(req.body.newPointOptional));
192
- group.set("configuration.hideHelpIcon", truthValueFromBody(req.body.hideHelpIcon));
193
- group.set("configuration.hideEmoji", truthValueFromBody(req.body.hideEmoji));
194
- group.set("configuration.hideGroupHeader", truthValueFromBody(req.body.hideGroupHeader));
195
- group.set("configuration.hidePointAuthor", truthValueFromBody(req.body.hidePointAuthor));
196
- group.set("configuration.hidePostAuthor", truthValueFromBody(req.body.hidePostAuthor));
197
- group.set("configuration.hideDownVoteForPost", truthValueFromBody(req.body.hideDownVoteForPost));
198
- group.set("configuration.attachmentsEnabled", truthValueFromBody(req.body.attachmentsEnabled));
199
- group.set("configuration.moreContactInformation", truthValueFromBody(req.body.moreContactInformation));
200
- group.set("configuration.moreContactInformationAddress", truthValueFromBody(req.body.moreContactInformationAddress));
201
- group.set("configuration.useContainImageMode", truthValueFromBody(req.body.useContainImageMode));
202
- group.set("configuration.endorsementButtons", req.body.endorsementButtons && req.body.endorsementButtons != ""
203
- ? req.body.endorsementButtons
204
- : "hearts");
205
- group.set("configuration.alternativeHeader", req.body.alternativeHeader && req.body.alternativeHeader != ""
206
- ? req.body.alternativeHeader
207
- : null);
208
- group.set("configuration.defaultLocationLongLat", req.body.defaultLocationLongLat && req.body.defaultLocationLongLat != ""
209
- ? req.body.defaultLocationLongLat
210
- : null);
211
- group.set("configuration.postDescriptionLimit", req.body.postDescriptionLimit && req.body.postDescriptionLimit != ""
212
- ? req.body.postDescriptionLimit
213
- : "500");
214
- if (truthValueFromBody(req.body.status)) {
215
- group.status = req.body.status;
216
- }
217
- if (truthValueFromBody(req.body.defaultLocale)) {
218
- group.set("configuration.defaultLocale", req.body.defaultLocale);
219
- }
220
- if (truthValueFromBody(req.body.uploadedDefaultDataImageId)) {
221
- group.set("configuration.defaultDataImageId", req.body.uploadedDefaultDataImageId);
222
- }
223
- if (truthValueFromBody(req.body.uploadedDefaultPostImageId)) {
224
- group.set("configuration.uploadedDefaultPostImageId", req.body.uploadedDefaultPostImageId);
225
- }
226
- group.set("configuration.alternativeTextForNewIdeaButton", req.body.alternativeTextForNewIdeaButton &&
227
- req.body.alternativeTextForNewIdeaButton !== ""
228
- ? req.body.alternativeTextForNewIdeaButton
229
- : null);
230
- group.set("configuration.alternativeTextForNewIdeaButtonClosed", req.body.alternativeTextForNewIdeaButtonClosed &&
231
- req.body.alternativeTextForNewIdeaButtonClosed !== ""
232
- ? req.body.alternativeTextForNewIdeaButtonClosed
233
- : null);
234
- group.set("configuration.alternativeTextForNewIdeaButtonHeader", req.body.alternativeTextForNewIdeaButtonHeader &&
235
- req.body.alternativeTextForNewIdeaButtonHeader !== ""
236
- ? req.body.alternativeTextForNewIdeaButtonHeader
237
- : null);
238
- group.set("configuration.alternativeTextForNewIdeaSaveButton", req.body.alternativeTextForNewIdeaSaveButton &&
239
- req.body.alternativeTextForNewIdeaSaveButton !== ""
240
- ? req.body.alternativeTextForNewIdeaSaveButton
241
- : null);
242
- group.set("configuration.customCategoryQuestionText", req.body.customCategoryQuestionText &&
243
- req.body.customCategoryQuestionText !== ""
244
- ? req.body.customCategoryQuestionText
245
- : null);
246
- group.set("configuration.alternativePointForHeader", req.body.alternativePointForHeader &&
247
- req.body.alternativePointForHeader != ""
248
- ? req.body.alternativePointForHeader
249
- : null);
250
- group.set("configuration.alternativePointAgainstHeader", req.body.alternativePointAgainstHeader &&
251
- req.body.alternativePointAgainstHeader != ""
252
- ? req.body.alternativePointAgainstHeader
253
- : null);
254
- group.set("configuration.alternativePointForLabel", req.body.alternativePointForLabel && req.body.alternativePointForLabel != ""
255
- ? req.body.alternativePointForLabel
256
- : null);
257
- group.set("configuration.alternativePointAgainstLabel", req.body.alternativePointAgainstLabel &&
258
- req.body.alternativePointAgainstLabel != ""
259
- ? req.body.alternativePointAgainstLabel
260
- : null);
261
- group.set("configuration.disableFacebookLoginForGroup", truthValueFromBody(req.body.disableFacebookLoginForGroup));
262
- group.set("configuration.disableNameAutoTranslation", truthValueFromBody(req.body.disableNameAutoTranslation));
263
- group.set("configuration.externalGoalTriggerUrl", req.body.externalGoalTriggerUrl && req.body.externalGoalTriggerUrl != ""
264
- ? req.body.externalGoalTriggerUrl
265
- : null);
266
- group.set("configuration.hideNewPost", truthValueFromBody(req.body.hideNewPost));
267
- group.set("configuration.disableCollectionUpLink", truthValueFromBody(req.body.disableCollectionUpLink));
268
- group.set("configuration.disableCommunityUpLink", truthValueFromBody(req.body.disableCommunityUpLink));
269
- group.set("configuration.makeCategoryRequiredOnNewPost", truthValueFromBody(req.body.makeCategoryRequiredOnNewPost));
270
- group.set("configuration.showVideoUploadDisclaimer", truthValueFromBody(req.body.showVideoUploadDisclaimer));
271
- group.set("configuration.welcomePageId", req.body.welcomePageId && req.body.welcomePageId != ""
272
- ? req.body.welcomePageId
273
- : null);
274
- group.set("configuration.hideVoteCount", truthValueFromBody(req.body.hideVoteCount));
275
- group.set("configuration.hideGroupType", truthValueFromBody(req.body.hideGroupType));
276
- group.set("configuration.hideVoteCountUntilVoteCompleted", truthValueFromBody(req.body.hideVoteCountUntilVoteCompleted));
277
- group.set("configuration.hidePostCover", truthValueFromBody(req.body.hidePostCover));
278
- group.set("configuration.hidePostDescription", truthValueFromBody(req.body.hidePostDescription));
279
- group.set("configuration.hideDebateIcon", truthValueFromBody(req.body.hideDebateIcon));
280
- group.set("configuration.hideSharing", truthValueFromBody(req.body.hideSharing));
281
- group.set("configuration.hidePointAgainst", truthValueFromBody(req.body.hidePointAgainst));
282
- group.set("configuration.disablePostPageLink", truthValueFromBody(req.body.disablePostPageLink));
283
- group.set("configuration.hidePostActionsInGrid", truthValueFromBody(req.body.hidePostActionsInGrid));
284
- group.set("configuration.forceSecureSamlLogin", truthValueFromBody(req.body.forceSecureSamlLogin));
285
- group.set("configuration.forceSecureSamlEmployeeLogin", truthValueFromBody(req.body.forceSecureSamlEmployeeLogin));
286
- group.set("configuration.galleryMode", truthValueFromBody(req.body.galleryMode));
287
- group.set("configuration.showNameUnderLogoImage", truthValueFromBody(req.body.showNameUnderLogoImage));
288
- group.set("configuration.alwaysHideLogoImage", truthValueFromBody(req.body.alwaysHideLogoImage));
289
- group.set("configuration.hideStatsAndMembership", truthValueFromBody(req.body.hideStatsAndMembership));
290
- group.set("configuration.centerGroupName", truthValueFromBody(req.body.centerGroupName));
291
- group.set("configuration.noGroupCardShadow", truthValueFromBody(req.body.noGroupCardShadow));
292
- group.set("configuration.hideNewestFromFilter", truthValueFromBody(req.body.hideNewestFromFilter));
293
- group.set("configuration.hideGroupLevelTabs", truthValueFromBody(req.body.hideGroupLevelTabs));
294
- group.set("configuration.hidePostFilterAndSearch", truthValueFromBody(req.body.hidePostFilterAndSearch));
295
- group.set("configuration.hidePostImageUploads", truthValueFromBody(req.body.hidePostImageUploads));
296
- group.set("configuration.hideNewPointOnNewIdea", truthValueFromBody(req.body.hideNewPointOnNewIdea));
297
- group.set("configuration.maxDaysBackForRecommendations", req.body.maxDaysBackForRecommendations &&
298
- req.body.maxDaysBackForRecommendations != ""
299
- ? req.body.maxDaysBackForRecommendations
300
- : null);
301
- group.set("configuration.groupType", req.body.groupType && req.body.groupType != "" ? req.body.groupType : null);
302
- group.set("configuration.externalId", req.body.externalId && req.body.externalId != ""
303
- ? req.body.externalId
304
- : null);
305
- group.set("configuration.usePostListFormatOnDesktop", truthValueFromBody(req.body.usePostListFormatOnDesktop));
306
- group.set("configuration.usePostTagsForPostListItems", truthValueFromBody(req.body.usePostTagsForPostListItems));
307
- group.set("configuration.usePostTagsForPostCards", truthValueFromBody(req.body.usePostTagsForPostCards));
308
- group.set("configuration.usePostTags", truthValueFromBody(req.body.usePostTags));
309
- group.set("configuration.closeNewsfeedSubmissions", truthValueFromBody(req.body.closeNewsfeedSubmissions));
310
- group.set("configuration.hideNewsfeeds", truthValueFromBody(req.body.hideNewsfeeds));
311
- group.set("configuration.allowGenerativeImages", truthValueFromBody(req.body.allowGenerativeImages));
312
- group.set("configuration.askUserIfNameShouldBeDisplayed", truthValueFromBody(req.body.askUserIfNameShouldBeDisplayed));
313
- group.set("configuration.allowPostVideoUploads", truthValueFromBody(req.body.allowPostVideoUploads));
314
- group.set("configuration.allowPointVideoUploads", truthValueFromBody(req.body.allowPointVideoUploads));
315
- group.set("configuration.useVideoCover", truthValueFromBody(req.body.useVideoCover));
316
- group.set("configuration.videoPostUploadLimitSec", req.body.videoPostUploadLimitSec && req.body.videoPostUploadLimitSec != ""
317
- ? req.body.videoPostUploadLimitSec
318
- : "60");
319
- group.set("configuration.videoPointUploadLimitSec", req.body.videoPointUploadLimitSec && req.body.videoPointUploadLimitSec != ""
320
- ? req.body.videoPointUploadLimitSec
321
- : "30");
322
- if (group.configuration.videoPostUploadLimitSec &&
323
- parseInt(group.configuration.videoPostUploadLimitSec)) {
324
- if (parseInt(group.configuration.videoPostUploadLimitSec) > 600) {
325
- group.set("configuration.videoPostUploadLimitSec", 600);
326
- }
327
- }
328
- if (group.configuration.videoPointUploadLimitSec &&
329
- parseInt(group.configuration.videoPointUploadLimitSec)) {
330
- if (parseInt(group.configuration.videoPointUploadLimitSec) > 600) {
331
- group.set("configuration.videoPointUploadLimitSec", 600);
332
- }
333
- }
334
- group.set("configuration.customTitleQuestionText", req.body.customTitleQuestionText && req.body.customTitleQuestionText != ""
335
- ? req.body.customTitleQuestionText
336
- : null);
337
- group.set("configuration.customFilterText", req.body.customFilterText && req.body.customFilterText != ""
338
- ? req.body.customFilterText
339
- : null);
340
- group.set("configuration.customBackURL", req.body.customBackURL && req.body.customBackURL != ""
341
- ? req.body.customBackURL
342
- : null);
343
- group.set("configuration.customBackName", req.body.customBackName && req.body.customBackName != ""
344
- ? req.body.customBackName
345
- : null);
346
- group.set("configuration.customVoteUpHoverText", req.body.customVoteUpHoverText && req.body.customVoteUpHoverText != ""
347
- ? req.body.customVoteUpHoverText
348
- : null);
349
- group.set("configuration.customVoteDownHoverText", req.body.customVoteDownHoverText && req.body.customVoteDownHoverText != ""
350
- ? req.body.customVoteDownHoverText
351
- : null);
352
- group.set("configuration.hideRecommendationOnNewsFeed", truthValueFromBody(req.body.hideRecommendationOnNewsFeed));
353
- group.set("configuration.useAsTemplate", truthValueFromBody(req.body.useAsTemplate));
354
- group.set("configuration.disableMachineTranscripts", truthValueFromBody(req.body.disableMachineTranscripts));
355
- group.set("configuration.hideLogoBoxExceptOnMobile", truthValueFromBody(req.body.hideLogoBoxExceptOnMobile));
356
- group.set("configuration.hideInfoBoxExceptForAdmins", truthValueFromBody(req.body.hideInfoBoxExceptForAdmins));
357
- group.set("configuration.hideLogoBoxShadow", truthValueFromBody(req.body.hideLogoBoxShadow));
358
- group.set("configuration.descriptionTruncateAmount", req.body.descriptionTruncateAmount &&
359
- req.body.descriptionTruncateAmount != ""
360
- ? req.body.descriptionTruncateAmount
361
- : null);
362
- group.set("configuration.descriptionSimpleFormat", truthValueFromBody(req.body.descriptionSimpleFormat));
363
- group.set("configuration.hidePointForAgainstIcons", truthValueFromBody(req.body.hidePointForAgainstIcons));
364
- group.set("configuration.transcriptSimpleFormat", truthValueFromBody(req.body.transcriptSimpleFormat));
365
- group.set("configuration.allowPostAudioUploads", truthValueFromBody(req.body.allowPostAudioUploads));
366
- group.set("configuration.allowPointAudioUploads", truthValueFromBody(req.body.allowPointAudioUploads));
367
- group.set("configuration.useAudioCover", truthValueFromBody(req.body.useAudioCover));
368
- group.set("configuration.audioPostUploadLimitSec", req.body.audioPostUploadLimitSec && req.body.audioPostUploadLimitSec != ""
369
- ? req.body.audioPostUploadLimitSec
370
- : "60");
371
- group.set("configuration.audioPointUploadLimitSec", req.body.audioPointUploadLimitSec && req.body.audioPointUploadLimitSec != ""
372
- ? req.body.audioPointUploadLimitSec
373
- : "30");
374
- if (group.configuration.audioPostUploadLimitSec &&
375
- parseInt(group.configuration.audioPostUploadLimitSec)) {
376
- if (parseInt(group.configuration.audioPostUploadLimitSec) > 600) {
377
- group.set("configuration.audioPostUploadLimitSec", 600);
378
- }
379
- }
380
- group.set("configuration.maxNumberOfGroupVotes", req.body.maxNumberOfGroupVotes && req.body.maxNumberOfGroupVotes != ""
381
- ? req.body.maxNumberOfGroupVotes
382
- : null);
383
- if (group.configuration.audioPointUploadLimitSec &&
384
- parseInt(group.configuration.audioPointUploadLimitSec)) {
385
- if (parseInt(group.configuration.audioPointUploadLimitSec) > 600) {
386
- group.set("configuration.audioPointUploadLimitSec", 600);
387
- }
388
- }
389
- group.set("configuration.urlToReviewActionText", req.body.urlToReviewActionText && req.body.urlToReviewActionText != ""
390
- ? req.body.urlToReviewActionText
391
- : null);
392
- group.set("configuration.structuredQuestions", req.body.structuredQuestions && req.body.structuredQuestions != ""
393
- ? req.body.structuredQuestions
394
- : null);
395
- if (group.configuration.structuredQuestions) {
396
- try {
397
- const cleaned = group.configuration.structuredQuestions
398
- .trim()
399
- .replace(/\n/g, "")
400
- .replace(/\r/g, "")
401
- .replace(/"/, '"');
402
- const jsonArray = JSON.parse(cleaned);
403
- const updatedJsonArray = [];
404
- let questionIndex = 0;
405
- jsonArray.forEach((question, index) => {
406
- if (question.type.toLowerCase() === "textfield" ||
407
- question.type.toLowerCase() === "textfieldlong" ||
408
- question.type.toLowerCase() === "textarea" ||
409
- question.type.toLowerCase() === "textarealong" ||
410
- question.type.toLowerCase() === "numberfield" ||
411
- question.type.toLowerCase() === "checkboxes" ||
412
- question.type.toLowerCase() === "radios" ||
413
- question.type.toLowerCase() === "dropdown") {
414
- question.questionIndex = questionIndex += 1;
415
- }
416
- updatedJsonArray.push(question);
417
- });
418
- group.set("configuration.structuredQuestionsJson", updatedJsonArray);
419
- }
420
- catch (error) {
421
- group.set("configuration.structuredQuestionsJson", null);
422
- log.error("Error in parsing structured questions", { error });
423
- }
424
- }
425
- else {
426
- group.set("configuration.structuredQuestionsJson", null);
427
- }
428
- group.set("configuration.registrationQuestions", req.body.registrationQuestions && req.body.registrationQuestions != ""
429
- ? req.body.registrationQuestions
430
- : null);
431
- if (group.configuration.registrationQuestions) {
432
- try {
433
- const cleaned = group.configuration.registrationQuestions
434
- .trim()
435
- .replace(/\n/g, "")
436
- .replace(/\r/g, "");
437
- const jsonArray = JSON.parse(cleaned);
438
- group.set("configuration.registrationQuestionsJson", jsonArray);
439
- }
440
- catch (error) {
441
- group.set("configuration.registrationQuestionsJson", null);
442
- log.error("Error in parsing registrationQuestions", { error });
443
- }
444
- }
445
- else {
446
- group.set("configuration.registrationQuestionsJson", null);
447
- }
448
- group.set("configuration.isDataVisualizationGroup", truthValueFromBody(req.body.isDataVisualizationGroup));
449
- group.set("configuration.dataForVisualization", req.body.dataForVisualization && req.body.dataForVisualization != ""
450
- ? req.body.dataForVisualization
451
- : null);
452
- if (group.configuration.dataForVisualization) {
453
- try {
454
- const cleaned = group.configuration.dataForVisualization
455
- .trim()
456
- .replace(/\n/g, "")
457
- .replace(/\r/g, "");
458
- const jsonArray = JSON.parse(cleaned);
459
- group.set("configuration.dataForVisualizationJson", jsonArray);
460
- }
461
- catch (error) {
462
- group.set("configuration.dataForVisualizationJson", null);
463
- log.error("Error in parsing dataForVisualization", { error });
464
- }
465
- }
466
- else {
467
- group.set("configuration.dataForVisualizationJson", null);
468
- }
469
- const ltpConfigText = req.body.ltp && req.body.ltp != "" ? req.body.ltp : null;
470
- if (ltpConfigText) {
471
- try {
472
- const cleaned = ltpConfigText
473
- .trim()
474
- .replace(/\n/g, "")
475
- .replace(/\r/g, "");
476
- const parsedJson = JSON.parse(cleaned);
477
- group.set("configuration.ltp", parsedJson);
478
- }
479
- catch (error) {
480
- group.set("configuration.ltp", null);
481
- log.error("Error in parsing ltp", { error });
482
- }
483
- }
484
- else {
485
- group.set("configuration.ltp", null);
486
- }
487
- const allOurIdeas = req.body.allOurIdeas && req.body.allOurIdeas != ""
488
- ? req.body.allOurIdeas
489
- : null;
490
- if (allOurIdeas) {
491
- try {
492
- const cleaned = allOurIdeas.trim().replace(/\n/g, "").replace(/\r/g, "");
493
- const parsedJson = JSON.parse(cleaned);
494
- group.set("configuration.allOurIdeas", parsedJson);
495
- }
496
- catch (error) {
497
- group.set("configuration.allOurIdeas", null);
498
- log.error("Error in parsing allOurIdeas", { error });
499
- }
500
- }
501
- else {
502
- group.set("configuration.allOurIdeas", null);
503
- }
504
- const staticHtml = req.body.staticHtml && req.body.staticHtml != ""
505
- ? req.body.staticHtml
506
- : null;
507
- if (staticHtml) {
508
- try {
509
- const cleaned = staticHtml.trim().replace(/\n/g, "").replace(/\r/g, "");
510
- const parsedJson = JSON.parse(cleaned);
511
- group.set("configuration.staticHtml", parsedJson);
512
- }
513
- catch (error) {
514
- group.set("configuration.staticHtml", undefined);
515
- log.error("Error in parsing staticHtml", { error });
516
- }
517
- }
518
- else {
519
- group.set("configuration.staticHtml", undefined);
520
- }
521
- const theme = req.body.theme && req.body.theme != "" ? req.body.theme : null;
522
- if (theme) {
523
- try {
524
- const cleaned = theme.trim().replace(/\n/g, "").replace(/\r/g, "");
525
- const parsedJson = JSON.parse(cleaned);
526
- group.set("configuration.theme", parsedJson);
527
- }
528
- catch (error) {
529
- group.set("configuration.theme", null);
530
- log.error("Error in parsing theme", { error });
531
- }
532
- }
533
- else {
534
- group.set("configuration.theme", null);
535
- }
536
- group.set("configuration.themeOverrideColorPrimary", req.body.themeOverrideColorPrimary &&
537
- req.body.themeOverrideColorPrimary != ""
538
- ? req.body.themeOverrideColorPrimary
539
- : null);
540
- group.set("configuration.themeOverrideColorAccent", req.body.themeOverrideColorAccent && req.body.themeOverrideColorAccent != ""
541
- ? req.body.themeOverrideColorAccent
542
- : null);
543
- group.set("configuration.customUserNamePrompt", req.body.customUserNamePrompt && req.body.customUserNamePrompt != ""
544
- ? req.body.customUserNamePrompt
545
- : null);
546
- group.set("configuration.customTermsIntroText", req.body.customTermsIntroText && req.body.customTermsIntroText != ""
547
- ? req.body.customTermsIntroText
548
- : null);
549
- const customRatingsText = req.body.customRatingsText && req.body.customRatingsText != ""
550
- ? req.body.customRatingsText
551
- : null;
552
- group.set("configuration.customRatingsText", customRatingsText);
553
- if (customRatingsText) {
554
- var ratingsComponents = customRatingsText.split(",");
555
- let ratings = [];
556
- if (ratingsComponents && ratingsComponents.length > 2) {
557
- for (var i = 0; i < ratingsComponents.length; i += 3) {
558
- ratings.push({
559
- name: ratingsComponents[i],
560
- numberOf: ratingsComponents[i + 1],
561
- emoji: ratingsComponents[i + 2],
562
- });
563
- }
564
- group.set("configuration.customRatings", ratings);
565
- }
566
- else {
567
- log.error("Ratings not in correct format for customRatings");
568
- }
569
- }
570
- else {
571
- group.set("configuration.customRatings", null);
572
- }
573
- group.set("configuration.customTabTitleNewLocation", req.body.customTabTitleNewLocation &&
574
- req.body.customTabTitleNewLocation !== ""
575
- ? req.body.customTabTitleNewLocation
576
- : null);
577
- group.set("configuration.allowAdminsToDebate", truthValueFromBody(req.body.allowAdminsToDebate));
578
- group.set("configuration.allowAdminAnswersToPoints", truthValueFromBody(req.body.allowAdminAnswersToPoints));
579
- group.set("configuration.forcePostSortMethodAs", req.body.forcePostSortMethodAs && req.body.forcePostSortMethodAs !== ""
580
- ? req.body.forcePostSortMethodAs
581
- : null);
582
- group.set("configuration.pointCharLimit", req.body.pointCharLimit && req.body.pointCharLimit !== ""
583
- ? req.body.pointCharLimit
584
- : null);
585
- group.set("configuration.allPostsBlockedByDefault", truthValueFromBody(req.body.allPostsBlockedByDefault));
586
- group.set("configuration.customThankYouTextNewPosts", req.body.customThankYouTextNewPosts &&
587
- req.body.customThankYouTextNewPosts !== ""
588
- ? req.body.customThankYouTextNewPosts
589
- : null);
590
- group.set("configuration.useCommunityTopBanner", truthValueFromBody(req.body.useCommunityTopBanner));
591
- group.set("configuration.makeMapViewDefault", truthValueFromBody(req.body.makeMapViewDefault));
592
- group.set("configuration.allowOneTimeLoginWithName", truthValueFromBody(req.body.allowOneTimeLoginWithName));
593
- group.set("configuration.simpleFormatDescription", truthValueFromBody(req.body.simpleFormatDescription));
594
- group.set("configuration.resourceLibraryLinkMode", truthValueFromBody(req.body.resourceLibraryLinkMode));
595
- group.set("configuration.collapsableTranscripts", truthValueFromBody(req.body.collapsableTranscripts));
596
- group.set("configuration.customAdminCommentsTitle", req.body.customAdminCommentsTitle &&
597
- req.body.customAdminCommentsTitle !== ""
598
- ? req.body.customAdminCommentsTitle
599
- : null);
600
- group.set("configuration.themeOverrideBackgroundColor", req.body.themeOverrideBackgroundColor &&
601
- req.body.themeOverrideBackgroundColor != ""
602
- ? req.body.themeOverrideBackgroundColor
603
- : null);
604
- group.set("configuration.hideNameInputAndReplaceWith", req.body.hideNameInputAndReplaceWith &&
605
- req.body.hideNameInputAndReplaceWith != ""
606
- ? req.body.hideNameInputAndReplaceWith
607
- : null);
608
- group.set("configuration.hideMediaInput", truthValueFromBody(req.body.hideMediaInput));
609
- group.set("configuration.actAsLinkToCommunityId", req.body.actAsLinkToCommunityId && req.body.actAsLinkToCommunityId != ""
610
- ? req.body.actAsLinkToCommunityId
611
- : null);
612
- group.set("configuration.hideQuestionIndexOnNewPost", truthValueFromBody(req.body.hideQuestionIndexOnNewPost));
613
- group.set("configuration.allowWhatsAppSharing", truthValueFromBody(req.body.allowWhatsAppSharing));
614
- group.set("configuration.inheritThemeFromCommunity", truthValueFromBody(req.body.inheritThemeFromCommunity));
615
- if (truthValueFromBody(req.body.inheritThemeFromCommunity) === true) {
616
- group.set("theme_id", null);
617
- }
618
- group.set("configuration.optionalSortOrder", req.body.optionalSortOrder && req.body.optionalSortOrder != ""
619
- ? req.body.optionalSortOrder
620
- : null);
621
- group.set("configuration.exportSubCodesForRadiosAndCheckboxes", truthValueFromBody(req.body.exportSubCodesForRadiosAndCheckboxes));
622
- group.set("configuration.forceShowDebateCountOnPost", truthValueFromBody(req.body.forceShowDebateCountOnPost));
623
- if (req.body.forAgentId &&
624
- req.body.forAgentId != "" &&
625
- req.body.inputOutput &&
626
- req.body.inputOutput != "") {
627
- group.set("configuration.agents", {
628
- inputConnectorForAgentId: req.body.inputOutput == "input" ? req.body.forAgentId : undefined,
629
- outputConnectorForAgentId: req.body.inputOutput == "output" ? req.body.forAgentId : undefined,
630
- });
631
- }
632
- };
633
- const getGroupFolder = function (req, done) {
634
- var groupFolder;
635
- log.info("getGroupFolder");
636
- async.series([
637
- function (seriesCallback) {
638
- models.Group.findOne({
639
- where: {
640
- id: req.params.groupFolderId,
641
- is_group_folder: true,
642
- },
643
- attributes: models.Group.defaultAttributesPublic,
644
- required: false,
645
- order: [
646
- ["counter_users", "desc"],
647
- [
648
- { model: models.Image, as: "GroupLogoImages" },
649
- "created_at",
650
- "asc",
651
- ],
652
- [
653
- { model: models.Image, as: "GroupHeaderImages" },
654
- "created_at",
655
- "asc",
656
- ],
657
- [{ model: models.Category }, "name", "asc"],
658
- ],
659
- include: models.Group.masterGroupIncludes(models),
660
- })
661
- .then(function (group) {
662
- groupFolder = group;
663
- if (groupFolder) {
664
- log.info("Group Folder Viewed", {
665
- groupFolderId: groupFolder.id,
666
- userId: req.user ? req.user.id : -1,
667
- });
668
- models.Group.addVideosAndCommunityLinksToGroups([groupFolder], (videoError) => {
669
- seriesCallback(videoError);
670
- });
671
- }
672
- else {
673
- seriesCallback("Not found");
674
- }
675
- return null;
676
- })
677
- .catch(function (error) {
678
- seriesCallback(error);
679
- });
680
- },
681
- function (seriesCallback) {
682
- const redisKey = "cache:groups_folder:" +
683
- groupFolder.id +
684
- ":" +
685
- models.Group.ACCESS_SECRET;
686
- req.redisClient
687
- .get(redisKey)
688
- .then((groups) => {
689
- if (groups) {
690
- groupFolder.dataValues.Groups = JSON.parse(groups);
691
- seriesCallback();
692
- }
693
- else {
694
- models.Group.findAll({
695
- where: {
696
- in_group_folder_id: groupFolder.id,
697
- access: {
698
- $ne: models.Group.ACCESS_SECRET,
699
- },
700
- status: {
701
- $ne: "hidden",
702
- },
703
- },
704
- attributes: models.Group.defaultAttributesPublic,
705
- required: false,
706
- order: [
707
- ["counter_users", "desc"],
708
- [
709
- { model: models.Image, as: "GroupLogoImages" },
710
- "created_at",
711
- "asc",
712
- ],
713
- [
714
- { model: models.Image, as: "GroupHeaderImages" },
715
- "created_at",
716
- "asc",
717
- ],
718
- [{ model: models.Category }, "name", "asc"],
719
- ],
720
- include: models.Group.masterGroupIncludes(models),
721
- })
722
- .then(function (groups) {
723
- groupFolder.dataValues.Groups = groups;
724
- req.redisClient.setEx(redisKey, process.env.GROUPS_CACHE_TTL
725
- ? parseInt(process.env.GROUPS_CACHE_TTL)
726
- : 3, JSON.stringify(groups));
727
- seriesCallback();
728
- })
729
- .catch((error) => {
730
- seriesCallback(error);
731
- });
732
- }
733
- })
734
- .catch((error) => {
735
- seriesCallback(error);
736
- });
737
- },
738
- function (seriesCallback) {
739
- if (req.user && groupFolder) {
740
- var adminGroups, userGroups;
741
- async.parallel([
742
- function (parallelCallback) {
743
- models.Group.findAll({
744
- where: {
745
- in_group_folder_id: groupFolder.id,
746
- },
747
- attributes: models.Group.defaultAttributesPublic,
748
- order: [
749
- ["counter_users", "desc"],
750
- [
751
- { model: models.Image, as: "GroupLogoImages" },
752
- "created_at",
753
- "asc",
754
- ],
755
- [
756
- { model: models.Image, as: "GroupHeaderImages" },
757
- "created_at",
758
- "asc",
759
- ],
760
- [{ model: models.Category }, "name", "asc"],
761
- ],
762
- include: [
763
- {
764
- model: models.User,
765
- as: "GroupAdmins",
766
- attributes: ["id"],
767
- required: true,
768
- through: { attributes: [] },
769
- where: {
770
- id: req.user.id,
771
- },
772
- },
773
- ].concat(models.Group.masterGroupIncludes(models)),
774
- })
775
- .then(function (groups) {
776
- adminGroups = groups;
777
- parallelCallback(null, "admin");
778
- })
779
- .catch(function (error) {
780
- parallelCallback(error);
781
- });
782
- },
783
- function (parallelCallback) {
784
- models.Group.findAll({
785
- where: {
786
- in_group_folder_id: groupFolder.id,
787
- },
788
- attributes: models.Group.defaultAttributesPublic,
789
- order: [
790
- ["counter_users", "desc"],
791
- [
792
- { model: models.Image, as: "GroupLogoImages" },
793
- "created_at",
794
- "asc",
795
- ],
796
- [
797
- { model: models.Image, as: "GroupHeaderImages" },
798
- "created_at",
799
- "asc",
800
- ],
801
- [{ model: models.Category }, "name", "asc"],
802
- ],
803
- include: [
804
- {
805
- model: models.User,
806
- as: "GroupUsers",
807
- attributes: ["id"],
808
- required: true,
809
- where: {
810
- id: req.user.id,
811
- },
812
- },
813
- ].concat(models.Group.masterGroupIncludes(models)),
814
- })
815
- .then(function (groups) {
816
- userGroups = groups;
817
- parallelCallback(null, "users");
818
- })
819
- .catch(function (error) {
820
- parallelCallback(error);
821
- });
822
- },
823
- ], function (error) {
824
- if (error) {
825
- seriesCallback(error);
826
- }
827
- else {
828
- var combinedGroups = _.concat(userGroups, groupFolder.dataValues.Groups);
829
- if (adminGroups) {
830
- combinedGroups = _.concat(adminGroups, combinedGroups);
831
- }
832
- combinedGroups = _.uniqBy(combinedGroups, function (group) {
833
- if (!group) {
834
- log.error("Can't find group in combinedGroups", {
835
- combinedGroupsL: combinedGroups.length,
836
- err: "Cant find group in combinedGroups",
837
- });
838
- return null;
839
- }
840
- else {
841
- return group.id;
842
- }
843
- });
844
- models.Group.addVideosAndCommunityLinksToGroups(combinedGroups, (videoError) => {
845
- groupFolder.dataValues.Groups = combinedGroups;
846
- seriesCallback(videoError);
847
- });
848
- }
849
- });
850
- }
851
- else {
852
- models.Group.addVideosAndCommunityLinksToGroups(groupFolder.dataValues.Groups, (videoError) => {
853
- seriesCallback(videoError);
854
- });
855
- }
856
- },
857
- ], function (error) {
858
- done(error, groupFolder);
859
- });
860
- };
861
- router.post("/:id/getPresignedAttachmentURL", auth.can("add to group"), function (req, res) {
862
- const endPoint = process.env.S3_ENDPOINT || "s3.amazonaws.com";
863
- const accelEndPoint = process.env.S3_ACCELERATED_ENDPOINT ||
864
- process.env.S3_ENDPOINT ||
865
- "s3.amazonaws.com";
866
- const s3 = new aws.S3({
867
- secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
868
- accessKeyId: process.env.AWS_ACCESS_KEY_ID,
869
- endpoint: accelEndPoint,
870
- signatureVersion: "v4",
871
- useAccelerateEndpoint: process.env.S3_ACCELERATED_ENDPOINT != null,
872
- region: process.env.S3_REGION ? process.env.S3_REGION : "eu-west-1",
873
- s3ForcePathStyle: process.env.S3_FORCE_PATH_STYLE ? true : false,
874
- });
875
- const signedUrlExpireSeconds = 60 * 60;
876
- const bucketName = process.env.S3_ATTACHMENTS_BUCKET;
877
- // const contentType = req.body.contentType ? req.body.contentType : 'application/octet-stream';
878
- const contentType = req.body.contentType
879
- ? req.body.contentType
880
- : "application/octet-stream";
881
- const randomCode = Math.random().toString(36).substring(2, 9);
882
- const fileKey = randomCode + "/" + req.body.filename;
883
- const s3Params = {
884
- Bucket: bucketName,
885
- Key: fileKey,
886
- Expires: signedUrlExpireSeconds,
887
- ACL: process.env.S3_FORCE_PATH_STYLE ? undefined : "public-read",
888
- ContentType: contentType,
889
- };
890
- s3.getSignedUrl("putObject", s3Params, (error, url) => {
891
- if (error) {
892
- log.error("Error getting presigned attachment url from AWS S3", {
893
- error,
894
- });
895
- res.sendStatus(500);
896
- }
897
- else {
898
- log.info("Presigned URL:", { url });
899
- res.send({ presignedUrl: url });
900
- }
901
- });
902
- });
903
- router.delete("/:groupId/:activityId/delete_activity", auth.can("edit group"), function (req, res) {
904
- models.AcActivity.findOne({
905
- where: {
906
- group_id: req.params.groupId,
907
- id: req.params.activityId,
908
- },
909
- })
910
- .then(function (activity) {
911
- activity.deleted = true;
912
- activity.save().then(function () {
913
- res.send({ activityId: activity.id });
914
- });
915
- })
916
- .catch(function (error) {
917
- log.error("Could not delete activity for group", {
918
- err: error,
919
- context: "delete_activity",
920
- user: toJson(req.user.simple()),
921
- });
922
- res.sendStatus(500);
923
- });
924
- });
925
- router.delete("/:groupId/user_membership", auth.isLoggedInNoAnonymousCheck, auth.can("view group"), function (req, res) {
926
- getGroupAndUser(req.params.groupId, req.user.id, null, function (error, group, user) {
927
- if (error) {
928
- log.error("Could not remove user", {
929
- err: error,
930
- groupId: req.params.groupId,
931
- userRemovedId: req.user.id,
932
- context: "user_membership",
933
- user: toJson(req.user.simple()),
934
- });
935
- res.sendStatus(500);
936
- }
937
- else if (user && group) {
938
- group.removeGroupUsers(user).then(function (results) {
939
- log.info("User removed", {
940
- context: "remove_admin",
941
- groupId: req.params.groupId,
942
- userRemovedId: req.user.id,
943
- user: toJson(req.user.simple()),
944
- });
945
- res.send({ membershipValue: false, name: group.name });
946
- });
947
- }
948
- else {
949
- res.sendStatus(404);
950
- }
951
- });
952
- });
953
- router.post("/:groupId/user_membership", auth.isLoggedInNoAnonymousCheck, auth.can("add to group"), function (req, res) {
954
- getGroupAndUser(req.params.groupId, req.user.id, null, function (error, group, user) {
955
- if (error) {
956
- log.error("Could not add user", {
957
- err: error,
958
- groupId: req.params.groupId,
959
- userRemovedId: req.user.id,
960
- context: "user_membership",
961
- user: toJson(req.user.simple()),
962
- });
963
- res.sendStatus(500);
964
- }
965
- else if (user && group) {
966
- group.addGroupUsers(user).then(function (results) {
967
- log.info("User Added", {
968
- context: "user_membership",
969
- groupId: req.params.groupId,
970
- userRemovedId: req.user.id,
971
- user: toJson(req.user.simple()),
972
- });
973
- res.send({ membershipValue: true, name: group.name });
974
- });
975
- }
976
- else {
977
- res.sendStatus(404);
978
- }
979
- });
980
- });
981
- router.post("/:groupId/sendEmailInvitesForAnons", auth.can("edit group"), async function (req, res) {
982
- try {
983
- const group = await models.Group.findOne({
984
- where: { id: req.params.groupId },
985
- attributes: ["id", "community_id"],
986
- });
987
- const emails = req.body.emails;
988
- if (!emails) {
989
- res.sendStatus(400);
990
- log.error("No emails provided", {
991
- emails,
992
- });
993
- return;
994
- }
995
- const emailArray = emails
996
- .split("\n")
997
- .map((email) => email.trim());
998
- // Validate each email
999
- const validEmails = emailArray.filter((email) => {
1000
- // Basic email validation regex
1001
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1002
- return emailRegex.test(email);
1003
- });
1004
- if (validEmails.length !== emailArray.length) {
1005
- log.error("Invalid email addresses", {
1006
- invalidEmails: emailArray.filter((email) => !validEmails.includes(email)),
1007
- });
1008
- }
1009
- const { AgentInviteManager } = await import("../agents/managers/emailInvitesManager.js");
1010
- for (const email of validEmails) {
1011
- const token = crypto.randomBytes(20).toString("hex");
1012
- const invite = await models.Invite.create({
1013
- token,
1014
- expires_at: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1 year expiry
1015
- type: models.Invite.INVITE_TO_COMMUNITY_AND_GROUP_AS_ANON,
1016
- community_id: group.community_id,
1017
- from_user_id: req.user.id,
1018
- });
1019
- const invite_link = `https://app.${req.ypDomain.domain_name}/group/${group.id}?anonInvite=1&token=${token}&forAgentBundle=1`;
1020
- await AgentInviteManager.sendInviteEmail(invite_link, req.body.agentRunId, group.id, req.user, email);
1021
- log.info("Invite Created", {
1022
- email,
1023
- inviteId: invite.id,
1024
- invite_link,
1025
- });
1026
- }
1027
- res.sendStatus(200);
1028
- }
1029
- catch (error) {
1030
- log.error("Error inviting user emails as anons", {
1031
- error,
1032
- });
1033
- res.sendStatus(500);
1034
- }
1035
- });
1036
- router.post("/:groupId/:userEmail/invite_user", auth.can("edit group"), function (req, res) {
1037
- var invite, user, token;
1038
- async.series([
1039
- function (callback) {
1040
- crypto.randomBytes(20, function (error, buf) {
1041
- token = buf.toString("hex");
1042
- callback(error);
1043
- });
1044
- },
1045
- function (callback) {
1046
- models.User.findOne({
1047
- where: { email: req.params.userEmail },
1048
- attributes: ["id", "email"],
1049
- })
1050
- .then(function (userIn) {
1051
- if (userIn) {
1052
- user = userIn;
1053
- }
1054
- callback();
1055
- })
1056
- .catch(function (error) {
1057
- callback(error);
1058
- });
1059
- },
1060
- function (callback) {
1061
- if (!req.query.addToGroupDirectly) {
1062
- models.Invite.create({
1063
- token: token,
1064
- expires_at: Date.now() + 3600000 * 24 * 30 * 365 * 1000,
1065
- type: models.Invite.INVITE_TO_GROUP,
1066
- group_id: req.params.groupId,
1067
- domain_id: req.ypDomain.id,
1068
- user_id: user ? user.id : null,
1069
- from_user_id: req.user.id,
1070
- metadata: { toEmail: req.params.userEmail },
1071
- })
1072
- .then(function (inviteIn) {
1073
- if (inviteIn) {
1074
- invite = inviteIn;
1075
- callback();
1076
- }
1077
- else {
1078
- callback("Invite not found");
1079
- }
1080
- })
1081
- .catch(function (error) {
1082
- callback(error);
1083
- });
1084
- }
1085
- else {
1086
- callback();
1087
- }
1088
- },
1089
- function (callback) {
1090
- if (!req.query.addToGroupDirectly) {
1091
- models.AcActivity.inviteCreated({
1092
- email: req.params.userEmail,
1093
- user_id: user ? user.id : null,
1094
- sender_user_id: req.user.id,
1095
- sender_name: req.user.name,
1096
- group_id: req.params.groupId,
1097
- domain_id: req.ypDomain.id,
1098
- invite_id: invite.id,
1099
- token: token,
1100
- }, function (error) {
1101
- callback(error);
1102
- });
1103
- }
1104
- else {
1105
- callback();
1106
- }
1107
- },
1108
- function (callback) {
1109
- if (user && req.query.addToGroupDirectly) {
1110
- models.Group.findOne({
1111
- where: {
1112
- id: req.params.groupId,
1113
- },
1114
- attributes: ["id"],
1115
- })
1116
- .then((group) => {
1117
- if (group) {
1118
- group
1119
- .addGroupUsers(user)
1120
- .then(() => {
1121
- callback();
1122
- })
1123
- .catch((error) => {
1124
- callback(error);
1125
- });
1126
- }
1127
- else {
1128
- callback("Can't find group");
1129
- }
1130
- })
1131
- .catch((error) => {
1132
- callback(error);
1133
- });
1134
- }
1135
- else {
1136
- callback();
1137
- }
1138
- },
1139
- ], function (error) {
1140
- if (error) {
1141
- log.error("Send Invite Error", {
1142
- user: user ? toJson(user) : null,
1143
- context: "invite_user",
1144
- loggedInUser: toJson(req.user),
1145
- err: error,
1146
- errorStatus: 500,
1147
- });
1148
- res.sendStatus(500);
1149
- }
1150
- else {
1151
- if (!user && req.query.addToGroupDirectly) {
1152
- log.info("Send Invite User Not Found To add", {
1153
- userEmail: req.params.userEmail,
1154
- user: null,
1155
- context: "invite_user_community",
1156
- loggedInUser: toJson(req.user),
1157
- });
1158
- res.sendStatus(404);
1159
- }
1160
- else {
1161
- log.info("Send Invite Activity Created", {
1162
- userEmail: req.params.userEmail,
1163
- user: user ? toJson(user) : null,
1164
- context: "invite_user",
1165
- loggedInUser: toJson(req.user),
1166
- });
1167
- res.sendStatus(200);
1168
- }
1169
- }
1170
- });
1171
- });
1172
- router.post("/:groupId/add_page", auth.can("edit group"), function (req, res) {
1173
- models.Page.newPage(req, { group_id: req.params.groupId, content: {}, title: {} }, function (error, pages) {
1174
- if (error) {
1175
- log.error("Could not create page for admin for group", {
1176
- err: error,
1177
- context: "new_page",
1178
- user: toJson(req.user.simple()),
1179
- });
1180
- res.sendStatus(500);
1181
- }
1182
- else {
1183
- log.info("New Community Page", {
1184
- context: "new_page",
1185
- user: toJson(req.user.simple()),
1186
- });
1187
- res.sendStatus(200);
1188
- }
1189
- });
1190
- });
1191
- router.post("/:domainId/create_community_for_group", auth.can("create community"), function (req, res) {
1192
- log.info("Creating Community for Group", {
1193
- context: "create",
1194
- user: toJson(req.user),
1195
- });
1196
- var admin_email = req.user.email;
1197
- var admin_name = "Administrator";
1198
- var community = models.Community.build({
1199
- name: "Community for Group: " + req.body.name,
1200
- description: "Community for Group",
1201
- access: 0,
1202
- status: "hidden",
1203
- domain_id: req.params.domainId,
1204
- user_id: req.user.id,
1205
- admin_email: admin_email,
1206
- admin_name: admin_name,
1207
- configuration: {
1208
- theme: {
1209
- oneColorScheme: "tonal",
1210
- variant: "monochrome",
1211
- },
1212
- onlyAdminsCanCreateGroups: true,
1213
- },
1214
- hostname: req.body.hostname || `${uuidv4()}.${req.ypDomain.domain_name}`,
1215
- user_agent: req.useragent.source,
1216
- ip_address: req.clientIp,
1217
- });
1218
- community
1219
- .save()
1220
- .then(function (newCommunity) {
1221
- log.info("Community Created", {
1222
- domainId: newCommunity.domain_id,
1223
- context: "create",
1224
- user: toJson(req.user),
1225
- });
1226
- req.params.communityId = newCommunity.id;
1227
- newCommunity.updateAllExternalCounters(req, "up", "counter_communities", function () {
1228
- newCommunity.addCommunityAdmins(req.user).then(function (results) {
1229
- createGroup(req, res);
1230
- });
1231
- });
1232
- })
1233
- .catch(function (error) {
1234
- log.error("Could not create community for group", {
1235
- err: error,
1236
- context: "create",
1237
- user: toJson(req.user),
1238
- });
1239
- res.sendStatus(500);
1240
- });
1241
- });
1242
- router.post("/:communityId", auth.can("create group"), function (req, res) {
1243
- createGroup(req, res);
1244
- });
1245
- router.delete("/:groupId/:userId/remove_admin", auth.can("edit group"), function (req, res) {
1246
- getGroupAndUser(req.params.groupId, req.params.userId, null, function (error, group, user) {
1247
- if (error) {
1248
- log.error("Could not remove admin", {
1249
- err: error,
1250
- groupId: req.params.groupId,
1251
- userRemovedId: req.params.userId,
1252
- context: "remove_admin",
1253
- user: toJson(req.user.simple()),
1254
- });
1255
- res.sendStatus(500);
1256
- }
1257
- else if (user && group) {
1258
- group.removeGroupAdmins(user).then(function (results) {
1259
- log.info("Admin removed", {
1260
- context: "remove_admin",
1261
- groupId: req.params.groupId,
1262
- userRemovedId: req.params.userId,
1263
- user: toJson(req.user.simple()),
1264
- });
1265
- res.sendStatus(200);
1266
- });
1267
- }
1268
- else {
1269
- res.sendStatus(404);
1270
- }
1271
- });
1272
- });
1273
- router.delete("/:groupId/:userId/remove_promoter", auth.can("edit group"), function (req, res) {
1274
- getGroupAndUser(req.params.groupId, req.params.userId, null, function (error, group, user) {
1275
- if (error) {
1276
- log.error("Could not remove promoter", {
1277
- err: error,
1278
- groupId: req.params.groupId,
1279
- userRemovedId: req.params.userId,
1280
- context: "remove_promoter",
1281
- user: toJson(req.user.simple()),
1282
- });
1283
- res.sendStatus(500);
1284
- }
1285
- else if (user && group) {
1286
- group.removeGroupPromoters(user).then(function (results) {
1287
- log.info("Promoter removed", {
1288
- context: "remove_promoter",
1289
- groupId: req.params.groupId,
1290
- userRemovedId: req.params.userId,
1291
- user: toJson(req.user.simple()),
1292
- });
1293
- res.sendStatus(200);
1294
- });
1295
- }
1296
- else {
1297
- res.sendStatus(404);
1298
- }
1299
- });
1300
- });
1301
- router.get("/:groupId/has_promotion_access", auth.can("view group"), async (req, res) => {
1302
- if (req.user) {
1303
- if (await req.user.hasPromotionAccess(req.params.groupId)) {
1304
- res.sendStatus(200);
1305
- }
1306
- else {
1307
- res.sendStatus(401);
1308
- }
1309
- }
1310
- else {
1311
- res.sendStatus(401);
1312
- }
1313
- });
1314
- router.delete("/:groupId/remove_many_admins", auth.can("edit group"), function (req, res) {
1315
- queue.add("process-deletion", {
1316
- type: "remove-many-group-admins",
1317
- userIds: req.body.userIds,
1318
- groupId: req.params.groupId,
1319
- }, "high");
1320
- log.info("Remove many admins started", {
1321
- context: "remove_many_admins",
1322
- groupId: req.params.groupId,
1323
- user: toJson(req.user.simple()),
1324
- });
1325
- res.sendStatus(200);
1326
- });
1327
- router.delete("/:groupId/remove_many_promoters", auth.can("edit group"), function (req, res) {
1328
- queue.add("process-deletion", {
1329
- type: "remove-many-group-promoters",
1330
- userIds: req.body.userIds,
1331
- groupId: req.params.groupId,
1332
- }, "high");
1333
- log.info("Remove many promoters started", {
1334
- context: "remove_many_promoters",
1335
- groupId: req.params.groupId,
1336
- user: toJson(req.user.simple()),
1337
- });
1338
- res.sendStatus(200);
1339
- });
1340
- router.delete("/:groupId/remove_many_users_and_delete_content", auth.can("edit group"), function (req, res) {
1341
- queue.add("process-deletion", {
1342
- type: "remove-many-group-users-and-delete-content",
1343
- userIds: req.body.userIds,
1344
- groupId: req.params.groupId,
1345
- }, "high");
1346
- log.info("Remove many and delete many users content", {
1347
- context: "remove_many_users_and_delete_content",
1348
- groupId: req.params.groupId,
1349
- user: toJson(req.user.simple()),
1350
- });
1351
- res.sendStatus(200);
1352
- });
1353
- router.delete("/:groupId/remove_many_users", auth.can("edit group"), function (req, res) {
1354
- queue.add("process-deletion", {
1355
- type: "remove-many-group-users",
1356
- userIds: req.body.userIds,
1357
- groupId: req.params.groupId,
1358
- }, "high");
1359
- log.info("Remove many admins started", {
1360
- context: "remove_many_users",
1361
- groupId: req.params.groupId,
1362
- user: toJson(req.user.simple()),
1363
- });
1364
- res.sendStatus(200);
1365
- });
1366
- router.delete("/:groupId/:userId/remove_and_delete_user_content", auth.can("edit group"), function (req, res) {
1367
- getGroupAndUser(req.params.groupId, req.params.userId, null, function (error, group, user) {
1368
- if (error) {
1369
- log.error("Could not remove_user", {
1370
- err: error,
1371
- groupId: req.params.groupId,
1372
- userRemovedId: req.params.userId,
1373
- context: "remove_user",
1374
- user: toJson(req.user.simple()),
1375
- });
1376
- res.sendStatus(500);
1377
- }
1378
- else if (user && group) {
1379
- group.removeGroupUsers(user).then(function (results) {
1380
- if (group.counter_users > 0) {
1381
- group.decrement("counter_users");
1382
- }
1383
- queue.add("process-deletion", {
1384
- type: "delete-group-user-content",
1385
- userId: req.params.userId,
1386
- groupId: req.params.groupId,
1387
- }, "high");
1388
- log.info("User removed", {
1389
- context: "remove_and_delete_user_content",
1390
- groupId: req.params.groupId,
1391
- userRemovedId: req.params.userId,
1392
- user: toJson(req.user.simple()),
1393
- });
1394
- res.sendStatus(200);
1395
- });
1396
- }
1397
- else {
1398
- res.sendStatus(404);
1399
- }
1400
- });
1401
- });
1402
- router.delete("/:groupId/:userId/remove_user", auth.can("edit group"), function (req, res) {
1403
- getGroupAndUser(req.params.groupId, req.params.userId, null, function (error, group, user) {
1404
- if (error) {
1405
- log.error("Could not remove_user", {
1406
- err: error,
1407
- groupId: req.params.groupId,
1408
- userRemovedId: req.params.userId,
1409
- context: "remove_user",
1410
- user: toJson(req.user.simple()),
1411
- });
1412
- res.sendStatus(500);
1413
- }
1414
- else if (user && group) {
1415
- group.removeGroupUsers(user).then(function (results) {
1416
- if (group.counter_users > 0) {
1417
- group.decrement("counter_users");
1418
- }
1419
- log.info("User removed", {
1420
- context: "remove_user",
1421
- groupId: req.params.groupId,
1422
- userRemovedId: req.params.userId,
1423
- user: toJson(req.user.simple()),
1424
- });
1425
- res.sendStatus(200);
1426
- });
1427
- }
1428
- else {
1429
- res.sendStatus(404);
1430
- }
1431
- });
1432
- });
1433
- router.post("/:groupId/:email/add_admin", auth.can("edit group"), function (req, res) {
1434
- getGroupAndUser(req.params.groupId, null, req.params.email, function (error, group, user) {
1435
- if (error) {
1436
- log.error("Could not add admin", {
1437
- err: error,
1438
- groupId: req.params.groupId,
1439
- userAddEmail: req.params.email,
1440
- context: "add_admin",
1441
- user: toJson(req.user.simple()),
1442
- });
1443
- res.sendStatus(500);
1444
- }
1445
- else if (user && group) {
1446
- group.addGroupAdmins(user).then(function (results) {
1447
- log.info("Admin Added", {
1448
- context: "add_admin",
1449
- groupId: req.params.groupId,
1450
- userAddEmail: req.params.email,
1451
- user: toJson(req.user.simple()),
1452
- });
1453
- res.sendStatus(200);
1454
- });
1455
- }
1456
- else {
1457
- res.sendStatus(404);
1458
- }
1459
- });
1460
- });
1461
- router.post("/:groupId/:email/add_promoter", auth.can("edit group"), function (req, res) {
1462
- getGroupAndUser(req.params.groupId, null, req.params.email, function (error, group, user) {
1463
- if (error) {
1464
- log.error("Could not add promoter", {
1465
- err: error,
1466
- groupId: req.params.groupId,
1467
- userAddEmail: req.params.email,
1468
- context: "add_promoter",
1469
- user: toJson(req.user.simple()),
1470
- });
1471
- res.sendStatus(500);
1472
- }
1473
- else if (user && group) {
1474
- group.addGroupPromoters(user).then(function (results) {
1475
- log.info("Promoter Added", {
1476
- context: "add_promoter",
1477
- groupId: req.params.groupId,
1478
- userAddEmail: req.params.email,
1479
- user: toJson(req.user.simple()),
1480
- });
1481
- res.sendStatus(200);
1482
- });
1483
- }
1484
- else {
1485
- res.sendStatus(404);
1486
- }
1487
- });
1488
- });
1489
- router.get("/:groupId/pages", auth.can("view group"), function (req, res) {
1490
- const redisKey = "cache:groupPages:" + req.params.groupId;
1491
- req.redisClient
1492
- .get(redisKey)
1493
- .then((pages) => {
1494
- if (pages) {
1495
- res.send(JSON.parse(pages));
1496
- }
1497
- else {
1498
- models.Group.findOne({
1499
- where: { id: req.params.groupId },
1500
- attributes: ["id"],
1501
- include: [
1502
- {
1503
- model: models.Community,
1504
- attributes: ["id"],
1505
- include: [
1506
- {
1507
- model: models.Domain,
1508
- attributes: ["id"],
1509
- },
1510
- ],
1511
- },
1512
- ],
1513
- })
1514
- .then(function (group) {
1515
- models.Page.getPages(req, {
1516
- group_id: req.params.groupId,
1517
- community_id: group.Community.id,
1518
- domain_id: group.Community.Domain.id,
1519
- }, function (error, pages) {
1520
- if (error) {
1521
- log.error("Could not get pages for group", {
1522
- err: error,
1523
- context: "pages",
1524
- user: req.user ? toJson(req.user.simple()) : null,
1525
- });
1526
- res.sendStatus(500);
1527
- }
1528
- else {
1529
- log.info("Got Pages", {
1530
- userId: req.user ? req.user.id : null,
1531
- });
1532
- req.redisClient.setEx(redisKey, process.env.PAGES_CACHE_TTL
1533
- ? parseInt(process.env.PAGES_CACHE_TTL)
1534
- : 3, JSON.stringify(pages));
1535
- res.send(pages);
1536
- }
1537
- });
1538
- return null;
1539
- })
1540
- .catch(function (error) {
1541
- log.error("Could not get pages for group", {
1542
- err: error,
1543
- context: "pages",
1544
- user: req.user ? toJson(req.user.simple()) : null,
1545
- });
1546
- res.sendStatus(500);
1547
- });
1548
- }
1549
- })
1550
- .catch((error) => {
1551
- log.error("Could not get pages for group from redis", {
1552
- err: error,
1553
- context: "pages",
1554
- userId: req.user ? req.user.id : null,
1555
- });
1556
- res.sendStatus(500);
1557
- });
1558
- });
1559
- router.get("/:groupId/pages_for_admin", auth.can("edit group"), function (req, res) {
1560
- models.Page.getPagesForAdmin(req, { group_id: req.params.groupId }, function (error, pages) {
1561
- if (error) {
1562
- log.error("Could not get page for admin for group", {
1563
- err: error,
1564
- context: "pages_for_admin",
1565
- user: toJson(req.user.simple()),
1566
- });
1567
- res.sendStatus(500);
1568
- }
1569
- else {
1570
- log.info("Got Pages For Admin", {
1571
- context: "pages_for_admin",
1572
- userId: req.user ? req.user.id : null,
1573
- });
1574
- res.send(pages);
1575
- }
1576
- });
1577
- });
1578
- router.put("/:groupId/:type/start_report_creation", auth.can("edit group"), function (req, res) {
1579
- models.AcBackgroundJob.createJob({}, {}, (error, jobId) => {
1580
- if (error) {
1581
- log.error("Could not create backgroundJob", {
1582
- err: error,
1583
- context: "start_report_creation",
1584
- user: toJson(req.user.simple()),
1585
- });
1586
- res.sendStatus(500);
1587
- }
1588
- else {
1589
- let reportType;
1590
- if (req.params.type === "docx") {
1591
- reportType = "start-docx-report-generation";
1592
- }
1593
- else if (req.params.type === "xls") {
1594
- reportType = "start-xls-report-generation";
1595
- }
1596
- queue.add("process-reports", {
1597
- type: reportType,
1598
- userId: req.user.id,
1599
- exportType: req.params.type,
1600
- translateLanguage: req.query.translateLanguage,
1601
- jobId: jobId,
1602
- groupId: req.params.groupId,
1603
- }, "critical");
1604
- res.send({ jobId });
1605
- }
1606
- });
1607
- });
1608
- router.get("/:groupId/:jobId/report_creation_progress", auth.can("edit group"), function (req, res) {
1609
- models.AcBackgroundJob.findOne({
1610
- where: {
1611
- id: req.params.jobId,
1612
- },
1613
- attributes: ["id", "progress", "error", "data"],
1614
- })
1615
- .then((job) => {
1616
- res.send(job);
1617
- })
1618
- .catch((error) => {
1619
- log.error("Could not get backgroundJob", {
1620
- err: error,
1621
- context: "start_report_creation",
1622
- user: toJson(req.user.simple()),
1623
- });
1624
- res.sendStatus(500);
1625
- });
1626
- });
1627
- //TODO: Fix this permission back to edit
1628
- router.post("/:groupId/:start_generating/ai_image", auth.can("view group"), function (req, res) {
1629
- models.AcBackgroundJob.createJob({}, {}, (error, jobId) => {
1630
- if (error) {
1631
- log.error("Could not create backgroundJob", {
1632
- err: error,
1633
- context: "start_generating_ai_image",
1634
- user: req.user ? toJson(req.user.simple()) : null,
1635
- });
1636
- res.sendStatus(500);
1637
- }
1638
- else {
1639
- queue.add("process-generative-ai", {
1640
- type: "collection-image",
1641
- //TODO: Look into this
1642
- userId: req.user ? req.user.id : 1,
1643
- jobId: jobId,
1644
- collectionId: req.params.groupId,
1645
- collectionType: "group",
1646
- prompt: req.body.prompt,
1647
- imageType: req.body.imageType,
1648
- }, "critical");
1649
- res.send({ jobId });
1650
- }
1651
- });
1652
- });
1653
- //TODO: Fix this permission back to edit
1654
- router.get("/:groupId/:jobId/poll_for_generating_ai_image", auth.can("view group"), function (req, res) {
1655
- models.AcBackgroundJob.findOne({
1656
- where: {
1657
- id: req.params.jobId,
1658
- },
1659
- attributes: ["id", "progress", "error", "data"],
1660
- })
1661
- .then((job) => {
1662
- res.send(job);
1663
- })
1664
- .catch((error) => {
1665
- log.error("Could not get backgroundJob", {
1666
- err: error,
1667
- context: "poll_for_generating_ai_image",
1668
- user: req.user ? toJson(req.user.simple()) : null,
1669
- });
1670
- res.sendStatus(500);
1671
- });
1672
- });
1673
- router.get("/:groupId/export_group", auth.can("edit group"), function (req, res) {
1674
- models.Group.findOne({
1675
- where: {
1676
- id: req.params.groupId,
1677
- },
1678
- attributes: ["id", "name", "community_id", "configuration"],
1679
- })
1680
- .then(function (group) {
1681
- if (group) {
1682
- getExportFileDataForGroup(group, req.ypDomain.domain_name, function (error, fileData) {
1683
- if (error) {
1684
- log.error("Could not export for group", {
1685
- err: error,
1686
- context: "export_group",
1687
- user: toJson(req.user.simple()),
1688
- });
1689
- res.sendStatus(500);
1690
- }
1691
- else {
1692
- log.info("Got Export Admin", {
1693
- context: "export_group",
1694
- user: toJson(req.user.simple()),
1695
- });
1696
- var groupName = sanitizeFilename(group.name).replace(/ /g, "");
1697
- var dateString = moment(new Date()).format("DD_MM_YY_HH_mm");
1698
- var filename = "ideas_and_points_group_export_" +
1699
- group.community_id +
1700
- "_" +
1701
- req.params.groupId +
1702
- "_" +
1703
- groupName +
1704
- "_" +
1705
- dateString +
1706
- ".csv";
1707
- res.set({
1708
- "content-type": "application/octet-stream; charset=utf-8",
1709
- });
1710
- res.charset = "utf-8";
1711
- res.attachment(filename);
1712
- res.send(fileData);
1713
- }
1714
- });
1715
- }
1716
- else {
1717
- log.error("Cant find group", {
1718
- err: error,
1719
- context: "export_group",
1720
- user: toJson(req.user.simple()),
1721
- });
1722
- res.sendStatus(404);
1723
- }
1724
- })
1725
- .catch(function (error) {
1726
- log.error("Could not export for group", {
1727
- err: error,
1728
- context: "export_group",
1729
- user: toJson(req.user.simple()),
1730
- });
1731
- res.sendStatus(500);
1732
- });
1733
- });
1734
- router.get("/:groupId/export_group_docx", auth.can("edit group"), async (req, res) => {
1735
- models.Group.findOne({
1736
- where: {
1737
- id: req.params.groupId,
1738
- },
1739
- attributes: [
1740
- "id",
1741
- "name",
1742
- "community_id",
1743
- "objectives",
1744
- "configuration",
1745
- "language",
1746
- ],
1747
- })
1748
- .then(function (group) {
1749
- if (group) {
1750
- exportGroupToDocx(group, req.ypDomain.domain_name, req.query.translateLanguage, function (error, fileData) {
1751
- if (error) {
1752
- log.error("Could not export for group", {
1753
- err: error,
1754
- context: "export_group",
1755
- user: toJson(req.user.simple()),
1756
- });
1757
- res.sendStatus(500);
1758
- }
1759
- else {
1760
- log.info("Got Export Admin", {
1761
- context: "export_group",
1762
- user: toJson(req.user.simple()),
1763
- });
1764
- var groupName = sanitizeFilename(group.name).replace(/ /g, "");
1765
- var dateString = moment(new Date()).format("DD_MM_YY_HH_mm");
1766
- var filename = "ideas_and_points_group_export_" +
1767
- group.community_id +
1768
- "_" +
1769
- req.params.groupId +
1770
- "_" +
1771
- groupName +
1772
- "_" +
1773
- dateString +
1774
- ".docx";
1775
- res.set({
1776
- "content-type": "application/application/vnd.openxmlformats-officedocument.wordprocessingml.document; charset=utf-8",
1777
- });
1778
- res.setHeader("Content-Disposition", "attachment; filename=" + filename);
1779
- res.charset = "utf-8";
1780
- res.attachment(filename);
1781
- res.send(fileData);
1782
- }
1783
- });
1784
- }
1785
- else {
1786
- log.error("Cant find group", {
1787
- err: error,
1788
- context: "export_group",
1789
- user: toJson(req.user.simple()),
1790
- });
1791
- res.sendStatus(404);
1792
- }
1793
- })
1794
- .catch(function (error) {
1795
- log.error("Could not export for group", {
1796
- err: error,
1797
- context: "export_group",
1798
- user: toJson(req.user.simple()),
1799
- });
1800
- res.sendStatus(500);
1801
- });
1802
- });
1803
- router.put("/:groupId/:pageId/update_page_locale", auth.can("edit group"), function (req, res) {
1804
- models.Page.updatePageLocale(req, { group_id: req.params.groupId, id: req.params.pageId }, function (error) {
1805
- if (error) {
1806
- log.error("Could not update locale for admin for group", {
1807
- err: error,
1808
- context: "update_page_locale",
1809
- user: toJson(req.user.simple()),
1810
- });
1811
- res.sendStatus(500);
1812
- }
1813
- else {
1814
- log.info("Community Page Locale Updated", {
1815
- context: "update_page_locale",
1816
- user: toJson(req.user.simple()),
1817
- });
1818
- res.sendStatus(200);
1819
- }
1820
- });
1821
- });
1822
- router.put("/:groupId/:pageId/update_page_weight", auth.can("edit group"), function (req, res) {
1823
- models.Page.updatePageWeight(req, { group_id: req.params.groupId, id: req.params.pageId }, function (error) {
1824
- if (error) {
1825
- log.error("Could not update locale for admin for group", {
1826
- err: error,
1827
- context: "update_page_locale",
1828
- user: toJson(req.user.simple()),
1829
- });
1830
- res.sendStatus(500);
1831
- }
1832
- else {
1833
- log.info("Community Page Locale Updated", {
1834
- context: "update_page_locale",
1835
- user: toJson(req.user.simple()),
1836
- });
1837
- res.sendStatus(200);
1838
- }
1839
- });
1840
- });
1841
- router.put("/:groupId/:pageId/publish_page", auth.can("edit group"), function (req, res) {
1842
- models.Page.publishPage(req, { group_id: req.params.groupId, id: req.params.pageId }, function (error) {
1843
- if (error) {
1844
- log.error("Could not publish page for admin for group", {
1845
- err: error,
1846
- context: "publish_page",
1847
- user: toJson(req.user.simple()),
1848
- });
1849
- res.sendStatus(500);
1850
- }
1851
- else {
1852
- log.info("Community Page Published", {
1853
- context: "publish_page",
1854
- user: toJson(req.user.simple()),
1855
- });
1856
- res.sendStatus(200);
1857
- }
1858
- });
1859
- });
1860
- router.put("/:groupId/:pageId/un_publish_page", auth.can("edit group"), function (req, res) {
1861
- models.Page.unPublishPage(req, { group_id: req.params.groupId, id: req.params.pageId }, function (error) {
1862
- if (error) {
1863
- log.error("Could not un-publish page for admin for group", {
1864
- err: error,
1865
- context: "un_publish_page",
1866
- user: toJson(req.user.simple()),
1867
- });
1868
- res.sendStatus(500);
1869
- }
1870
- else {
1871
- log.info("Community Page Un-Published", {
1872
- context: "un_publish_page",
1873
- user: toJson(req.user.simple()),
1874
- });
1875
- res.sendStatus(200);
1876
- }
1877
- });
1878
- });
1879
- router.delete("/:groupId/:pageId/delete_page", auth.can("edit group"), function (req, res) {
1880
- models.Page.deletePage(req, { group_id: req.params.groupId, id: req.params.pageId }, function (error) {
1881
- if (error) {
1882
- log.error("Could not delete page for admin for group", {
1883
- err: error,
1884
- context: "delete_page",
1885
- user: toJson(req.user.simple()),
1886
- });
1887
- res.sendStatus(500);
1888
- }
1889
- else {
1890
- log.info("Commuity Page Published", {
1891
- context: "delete_page",
1892
- user: toJson(req.user.simple()),
1893
- });
1894
- res.sendStatus(200);
1895
- }
1896
- });
1897
- });
1898
- router.post("/:groupId/post/news_story", auth.isLoggedInNoAnonymousCheck, auth.can("add to group"), function (req, res) {
1899
- models.Point.createNewsStory(req, req.body, function (error) {
1900
- if (error) {
1901
- log.error("Could not save news story point on post", {
1902
- err: error,
1903
- context: "news_story",
1904
- user: toJson(req.user.simple()),
1905
- });
1906
- res.sendStatus(500);
1907
- }
1908
- else {
1909
- log.info("Point News Story Created", {
1910
- context: "news_story",
1911
- user: toJson(req.user.simple()),
1912
- });
1913
- res.sendStatus(200);
1914
- }
1915
- });
1916
- });
1917
- router.post("/:groupId/news_story", auth.isLoggedInNoAnonymousCheck, auth.can("add to group"), function (req, res) {
1918
- models.Point.createNewsStory(req, req.body, function (error, point) {
1919
- if (error) {
1920
- log.error("Could not save news story point on group", {
1921
- err: error,
1922
- context: "news_story",
1923
- user: toJson(req.user.simple()),
1924
- });
1925
- res.sendStatus(500);
1926
- }
1927
- else {
1928
- log.info("Point News Story Created", {
1929
- context: "news_story",
1930
- user: toJson(req.user.simple()),
1931
- });
1932
- res.send({
1933
- point_id: point ? point.id : null,
1934
- });
1935
- }
1936
- });
1937
- });
1938
- router.get("/:groupId/admin_users", auth.can("edit group"), function (req, res) {
1939
- models.Group.findOne({
1940
- where: {
1941
- id: req.params.groupId,
1942
- },
1943
- include: [
1944
- {
1945
- model: models.User,
1946
- attributes: _.concat(models.User.defaultAttributesWithSocialMediaPublicAndEmail, ["created_at", "last_login_at"]),
1947
- as: "GroupAdmins",
1948
- through: { attributes: [] },
1949
- required: true,
1950
- include: [
1951
- {
1952
- model: models.Organization,
1953
- attributes: ["id", "name"],
1954
- as: "OrganizationUsers",
1955
- required: false,
1956
- },
1957
- ],
1958
- },
1959
- ],
1960
- })
1961
- .then(function (group) {
1962
- log.info("Got admin users", {
1963
- context: "admin_users",
1964
- user: toJson(req.user.simple()),
1965
- });
1966
- if (group) {
1967
- res.send(group.GroupAdmins);
1968
- }
1969
- else {
1970
- res.send([]);
1971
- }
1972
- })
1973
- .catch(function (error) {
1974
- log.error("Could not get admin users", {
1975
- err: error,
1976
- context: "admin_users",
1977
- user: toJson(req.user.simple()),
1978
- });
1979
- res.sendStatus(500);
1980
- });
1981
- });
1982
- router.get("/:groupId/promotion_users", auth.can("edit group"), function (req, res) {
1983
- models.Group.findOne({
1984
- where: {
1985
- id: req.params.groupId,
1986
- },
1987
- include: [
1988
- {
1989
- model: models.User,
1990
- attributes: _.concat(models.User.defaultAttributesWithSocialMediaPublicAndEmail, ["created_at", "last_login_at"]),
1991
- as: "GroupPromoters",
1992
- required: true,
1993
- through: { attributes: [] },
1994
- include: [
1995
- {
1996
- model: models.Organization,
1997
- attributes: ["id", "name"],
1998
- as: "OrganizationUsers",
1999
- required: false,
2000
- },
2001
- ],
2002
- },
2003
- ],
2004
- })
2005
- .then(function (group) {
2006
- log.info("Got promotion users", {
2007
- context: "promotion_users",
2008
- user: toJson(req.user.simple()),
2009
- });
2010
- if (group) {
2011
- res.send(group.GroupPromoters);
2012
- }
2013
- else {
2014
- res.send([]);
2015
- }
2016
- })
2017
- .catch(function (error) {
2018
- log.error("Could not get promotion users", {
2019
- err: error,
2020
- context: "promotion_users",
2021
- user: toJson(req.user.simple()),
2022
- });
2023
- res.sendStatus(500);
2024
- });
2025
- });
2026
- router.get("/:groupId/users", auth.can("edit group"), function (req, res) {
2027
- models.Group.findOne({
2028
- where: {
2029
- id: req.params.groupId,
2030
- },
2031
- include: [
2032
- {
2033
- model: models.User,
2034
- attributes: _.concat(models.User.defaultAttributesWithSocialMediaPublicAndEmail, ["created_at", "last_login_at"]),
2035
- as: "GroupUsers",
2036
- required: true,
2037
- through: { attributes: [] },
2038
- include: [
2039
- {
2040
- model: models.Organization,
2041
- attributes: ["id", "name"],
2042
- as: "OrganizationUsers",
2043
- required: false,
2044
- },
2045
- ],
2046
- },
2047
- ],
2048
- })
2049
- .then(function (group) {
2050
- log.info("Got users", {
2051
- context: "users",
2052
- user: toJson(req.user.simple()),
2053
- });
2054
- if (group) {
2055
- res.send(group.GroupUsers);
2056
- }
2057
- else {
2058
- res.send([]);
2059
- }
2060
- })
2061
- .catch(function (error) {
2062
- log.error("Could not get admin users", {
2063
- err: error,
2064
- context: "users",
2065
- user: toJson(req.user.simple()),
2066
- });
2067
- res.sendStatus(500);
2068
- });
2069
- });
2070
- router.get("/:groupId/default_post_image/:imageId", auth.can("view group"), function (req, res) {
2071
- models.Image.findOne({
2072
- where: {
2073
- id: req.params.imageId,
2074
- },
2075
- })
2076
- .then(function (image) {
2077
- if (image) {
2078
- var formats = JSON.parse(image.formats);
2079
- res.redirect(formats[0]);
2080
- }
2081
- else {
2082
- res.sendStatus(200);
2083
- }
2084
- })
2085
- .catch(function (error) {
2086
- log.error("Could not get image", {
2087
- err: error,
2088
- context: "post_default_image",
2089
- });
2090
- res.sendStatus(500);
2091
- });
2092
- });
2093
- //TODO: Refactor this as not to repeate it in controlelrs
2094
- const addAgentFabricUserToSessionIfNeeded = async (req) => {
2095
- let userId = req.user && req.user.id ? req.user.id : null;
2096
- if (!userId &&
2097
- req.query.agentFabricUserId &&
2098
- process.env.PS_TEMP_AGENTS_FABRIC_GROUP_API_KEY &&
2099
- req.headers["x-api-key"] === process.env.PS_TEMP_AGENTS_FABRIC_GROUP_API_KEY) {
2100
- log.info(`Creating group with temp agents fabric group api key ${req.query.agentFabricUserId}`);
2101
- userId = req.query.agentFabricUserId;
2102
- try {
2103
- const loadedUser = await models.User.findByPk(userId);
2104
- req.user = loadedUser;
2105
- }
2106
- catch (error) {
2107
- log.error(`Could not find user with id ${userId}`, {
2108
- context: "create",
2109
- userId: userId,
2110
- error: error,
2111
- });
2112
- throw error;
2113
- }
2114
- }
2115
- else {
2116
- log.info("Creating group with user id: " + userId);
2117
- }
2118
- };
2119
- const copyThemeAndLogoFromAgentFabricGroup = async (newGroup, agentFabricGroup) => {
2120
- if (agentFabricGroup.configuration && agentFabricGroup.configuration.theme) {
2121
- newGroup.configuration.theme = { ...agentFabricGroup.configuration.theme };
2122
- await newGroup.save();
2123
- }
2124
- if (agentFabricGroup.GroupLogoImages &&
2125
- agentFabricGroup.GroupLogoImages.length > 0) {
2126
- log.info("Copying logo images from agent fabric group");
2127
- for (const logoImage of agentFabricGroup.GroupLogoImages) {
2128
- log.info(`Copying logo image ${logoImage.id} from agent fabric group`);
2129
- await newGroup.addGroupLogoImage(logoImage);
2130
- }
2131
- }
2132
- };
2133
- const createGroup = async (req, res) => {
2134
- console.log("Creating group with community id: " + req.params.communityId);
2135
- if (!req.user) {
2136
- try {
2137
- await addAgentFabricUserToSessionIfNeeded(req);
2138
- }
2139
- catch (error) {
2140
- log.error("Could not add agent fabric user to session", {
2141
- context: "create",
2142
- userId: req.user.id,
2143
- error: error,
2144
- });
2145
- res.sendStatus(500);
2146
- return;
2147
- }
2148
- }
2149
- var group = models.Group.build({
2150
- name: req.body.name,
2151
- objectives: req.body.objectives || req.body.description,
2152
- access: models.Group.convertAccessFromRadioButtons(req.body),
2153
- domain_id: req.ypDomain.id,
2154
- user_id: req.user.id,
2155
- community_id: req.params.communityId,
2156
- user_agent: req.useragent.source,
2157
- ip_address: req.clientIp,
2158
- });
2159
- group.theme_id = req.body.themeId ? parseInt(req.body.themeId) : null;
2160
- if (req.body.in_group_folder_id) {
2161
- group.in_group_folder_id = parseInt(req.body.in_group_folder_id);
2162
- }
2163
- if (req.body.is_group_folder && req.body.is_group_folder === "true") {
2164
- group.is_group_folder = true;
2165
- }
2166
- group.access = models.Group.convertAccessFromRadioButtons(req.body);
2167
- updateGroupConfigParameters(req, group);
2168
- group
2169
- .save()
2170
- .then(async function (group) {
2171
- log.info("Group Created", {
2172
- groupId: group.id,
2173
- context: "create",
2174
- userId: req.user.id,
2175
- });
2176
- queue.add("process-similarities", { type: "update-collection", groupId: group.id }, "low");
2177
- if (req.query.agentFabricGroupId) {
2178
- try {
2179
- const agentFabricGroup = await models.Group.findByPk(req.query.agentFabricGroupId, {
2180
- include: [
2181
- {
2182
- model: models.Image,
2183
- as: "GroupLogoImages",
2184
- },
2185
- ],
2186
- });
2187
- if (agentFabricGroup) {
2188
- await copyThemeAndLogoFromAgentFabricGroup(group, agentFabricGroup);
2189
- }
2190
- }
2191
- catch (error) {
2192
- log.error("Error copying theme and logo from agent fabric group", {
2193
- context: "create",
2194
- newGroupId: group.id,
2195
- agentFabricGroupId: req.query.agentFabricGroupId,
2196
- error: error,
2197
- });
2198
- }
2199
- }
2200
- group.updateAllExternalCounters(req, "up", "counter_groups", function () {
2201
- models.Group.addUserToGroupIfNeeded(group.id, req, function () {
2202
- group.addGroupAdmins(req.user).then(function (results) {
2203
- group.setupImages(req, group.id, function (error) {
2204
- queue.add("process-moderation", {
2205
- type: "estimate-collection-toxicity",
2206
- collectionId: group.id,
2207
- collectionType: "group",
2208
- }, "high");
2209
- queue.add("process-moderation", {
2210
- type: "collection-review-and-annotate-images",
2211
- collectionId: group.id,
2212
- collectionType: "group",
2213
- }, "medium");
2214
- if (group.configuration.groupType == 3) {
2215
- import("../agents/controllers/policySynthAgents.js").then(({ PolicySynthAgentsController }) => {
2216
- PolicySynthAgentsController.setupApiKeysForGroup(group)
2217
- .then(() => {
2218
- log.info("Policy Synth Agents Api Keys Created", {
2219
- groupId: group.id,
2220
- context: "create",
2221
- userId: req.user.id,
2222
- });
2223
- sendGroupOrError(res, group, "createGroup", req.user, error);
2224
- })
2225
- .catch((error) => {
2226
- sendGroupOrError(res, group, "createGroup", req.user, error);
2227
- log.error("Policy Synth Agents Api Keys Not Created", {
2228
- groupId: group.id,
2229
- context: "create",
2230
- userId: req.user.id,
2231
- error: error,
2232
- });
2233
- });
2234
- });
2235
- }
2236
- else {
2237
- sendGroupOrError(res, group, "createGroup", req.user, error);
2238
- }
2239
- });
2240
- });
2241
- });
2242
- });
2243
- })
2244
- .catch(function (error) {
2245
- sendGroupOrError(res, null, "create", req.user, error);
2246
- });
2247
- };
2248
- router.put("/:id", auth.can("edit group"), function (req, res) {
2249
- models.Group.findOne({
2250
- where: { id: req.params.id },
2251
- order: [
2252
- [{ model: models.Image, as: "GroupLogoImages" }, "created_at", "asc"],
2253
- [{ model: models.Image, as: "GroupHeaderImages" }, "created_at", "asc"],
2254
- [{ model: models.Video, as: "GroupLogoVideos" }, "updated_at", "desc"],
2255
- [
2256
- { model: models.Video, as: "GroupLogoVideos" },
2257
- { model: models.Image, as: "VideoImages" },
2258
- "updated_at",
2259
- "asc",
2260
- ],
2261
- ],
2262
- include: [
2263
- {
2264
- model: models.Community,
2265
- required: true,
2266
- attributes: ["id", "access"],
2267
- },
2268
- {
2269
- model: models.Image,
2270
- as: "GroupLogoImages",
2271
- attributes: models.Image.defaultAttributesPublic,
2272
- required: false,
2273
- },
2274
- {
2275
- model: models.Video,
2276
- as: "GroupLogoVideos",
2277
- attributes: ["id", "formats", "viewable", "public_meta"],
2278
- required: false,
2279
- include: [
2280
- {
2281
- model: models.Image,
2282
- as: "VideoImages",
2283
- attributes: ["formats", "updated_at"],
2284
- required: false,
2285
- },
2286
- ],
2287
- },
2288
- {
2289
- model: models.Image,
2290
- as: "GroupHeaderImages",
2291
- attributes: models.Image.defaultAttributesPublic,
2292
- required: false,
2293
- },
2294
- ],
2295
- })
2296
- .then(function (group) {
2297
- if (group) {
2298
- group.name = req.body.name;
2299
- group.objectives = req.body.objectives || req.body.description;
2300
- group.theme_id = req.body.themeId ? parseInt(req.body.themeId) : null;
2301
- group.access = models.Group.convertAccessFromRadioButtons(req.body);
2302
- updateGroupConfigParameters(req, group);
2303
- if (req.body.moveGroupTo) {
2304
- moveGroupTo(req, group);
2305
- }
2306
- group
2307
- .save()
2308
- .then(function () {
2309
- log.info("Group Updated", {
2310
- group: toJson(group),
2311
- context: "update",
2312
- user: toJson(req.user),
2313
- });
2314
- queue.add("process-similarities", { type: "update-collection", groupId: group.id }, "low");
2315
- group.setupImages(req, req.params.id, function (error) {
2316
- queue.add("process-moderation", {
2317
- type: "estimate-collection-toxicity",
2318
- collectionId: group.id,
2319
- collectionType: "group",
2320
- }, "high");
2321
- queue.add("process-moderation", {
2322
- type: "collection-review-and-annotate-images",
2323
- collectionId: group.id,
2324
- collectionType: "group",
2325
- }, "medium");
2326
- if (group.configuration.groupType == 3) {
2327
- import("../agents/controllers/policySynthAgents.js").then(({ PolicySynthAgentsController }) => {
2328
- PolicySynthAgentsController.setupApiKeysForGroup(group)
2329
- .then(() => {
2330
- log.info("Policy Synth Agents Api Keys Created", {
2331
- groupId: group.id,
2332
- context: "create",
2333
- userId: req.user.id,
2334
- });
2335
- sendGroupOrError(res, group, "setupImages", req.user, error);
2336
- })
2337
- .catch((error) => {
2338
- sendGroupOrError(res, group, "createGroup", req.user, error);
2339
- log.error("Policy Synth Agents Api Keys Not Created", {
2340
- groupId: group.id,
2341
- context: "create",
2342
- userId: req.user.id,
2343
- error: error,
2344
- });
2345
- });
2346
- });
2347
- }
2348
- else {
2349
- sendGroupOrError(res, group, "setupImages", req.user, error);
2350
- }
2351
- });
2352
- })
2353
- .catch(function (error) {
2354
- sendGroupOrError(res, null, "update", req.user, error);
2355
- });
2356
- }
2357
- else {
2358
- sendGroupOrError(res, req.params.id, "update", req.user, "Not found", 404);
2359
- }
2360
- })
2361
- .catch(function (error) {
2362
- sendGroupOrError(res, null, "update", req.user, error);
2363
- });
2364
- });
2365
- router.delete("/:id", auth.can("edit group"), function (req, res) {
2366
- models.Group.findOne({
2367
- where: { id: req.params.id },
2368
- })
2369
- .then(function (group) {
2370
- if (group) {
2371
- group.deleted = true;
2372
- group.save().then(function () {
2373
- log.info("Group Deleted", {
2374
- group: toJson(group),
2375
- context: "delete",
2376
- user: toJson(req.user),
2377
- });
2378
- queue.add("process-similarities", { type: "update-collection", groupId: group.id }, "low");
2379
- queue.add("process-deletion", {
2380
- type: "delete-group-content",
2381
- resetCounters: true,
2382
- groupName: group.name,
2383
- userId: req.user.id,
2384
- groupId: group.id,
2385
- }, "critical");
2386
- group.updateAllExternalCounters(req, "down", "counter_groups", function () {
2387
- res.sendStatus(200);
2388
- });
2389
- });
2390
- }
2391
- else {
2392
- sendGroupOrError(res, req.params.id, "delete", req.user, "Not found", 404);
2393
- }
2394
- })
2395
- .catch(function (error) {
2396
- sendGroupOrError(res, null, "delete", req.user, error);
2397
- });
2398
- });
2399
- router.delete("/:id/delete_content", auth.can("edit group"), function (req, res) {
2400
- models.Group.findOne({
2401
- where: { id: req.params.id },
2402
- })
2403
- .then(function (group) {
2404
- if (group) {
2405
- log.info("Group Delete Content", {
2406
- group: toJson(group),
2407
- context: "delete",
2408
- user: toJson(req.user),
2409
- });
2410
- queue.add("process-deletion", {
2411
- type: "delete-group-content",
2412
- groupName: group.name,
2413
- userId: req.user.id,
2414
- groupId: group.id,
2415
- useNotification: true,
2416
- resetCounters: true,
2417
- }, "critical");
2418
- res.sendStatus(200);
2419
- }
2420
- else {
2421
- sendGroupOrError(res, req.params.id, "delete", req.user, "Not found", 404);
2422
- }
2423
- })
2424
- .catch(function (error) {
2425
- sendGroupOrError(res, null, "delete", req.user, error);
2426
- });
2427
- });
2428
- router.delete("/:id/anonymize_content", auth.can("edit group"), function (req, res) {
2429
- const anonymizationDelayMs = 1000 * 60 * 60 * 24 * 7;
2430
- models.Group.findOne({
2431
- where: { id: req.params.id },
2432
- })
2433
- .then(function (group) {
2434
- if (group) {
2435
- log.info("Group Anonymize Content with delay", {
2436
- group: toJson(group),
2437
- anonymizationDelayMs: anonymizationDelayMs,
2438
- context: "delete",
2439
- userId: toJson(req.user.id),
2440
- });
2441
- queue.add("process-anonymization", {
2442
- type: "notify-group-users",
2443
- groupName: group.name,
2444
- userId: req.user.id,
2445
- groupId: group.id,
2446
- delayMs: anonymizationDelayMs,
2447
- }, "high");
2448
- queue.add("process-anonymization", {
2449
- type: "anonymize-group-content",
2450
- groupName: group.name,
2451
- userId: req.user.id,
2452
- groupId: group.id,
2453
- useNotification: true,
2454
- resetCounters: true,
2455
- }, "high", { delay: anonymizationDelayMs });
2456
- res.sendStatus(200);
2457
- }
2458
- else {
2459
- sendGroupOrError(res, req.params.id, "delete", req.user, "Not found", 404);
2460
- }
2461
- })
2462
- .catch(function (error) {
2463
- sendGroupOrError(res, null, "delete", req.user, error);
2464
- });
2465
- });
2466
- router.post("/:id/clone", auth.can("edit group"), function (req, res) {
2467
- models.Group.findOne({
2468
- attributes: ["id", "community_id"],
2469
- where: { id: req.params.id },
2470
- include: [
2471
- {
2472
- model: models.Community,
2473
- attributes: ["id", "domain_id"],
2474
- include: [
2475
- {
2476
- model: models.Domain,
2477
- attributes: ["id"],
2478
- },
2479
- ],
2480
- },
2481
- ],
2482
- })
2483
- .then(function (group) {
2484
- if (group) {
2485
- copyGroup(group.id, group.Community, group.Community.domain_id, { skipUsers: true, skipActivities: true }, (error, newGroup) => {
2486
- if (error) {
2487
- log.error("Group Cloned Failed", {
2488
- error,
2489
- groupId: req.params.id,
2490
- });
2491
- res.sendStatus(500);
2492
- }
2493
- else if (newGroup) {
2494
- log.info("Group Cloned", { groupId: req.params.id });
2495
- res.send({ id: newGroup.id });
2496
- }
2497
- else {
2498
- log.error("Group Cloned succeeded but newGroup is missing", { groupId: req.params.id });
2499
- res.sendStatus(500);
2500
- }
2501
- });
2502
- }
2503
- else {
2504
- sendGroupOrError(res, req.params.id, "delete", req.user, "Not found", 404);
2505
- }
2506
- })
2507
- .catch(function (error) {
2508
- sendGroupOrError(res, null, "delete", req.user, error);
2509
- });
2510
- });
2511
- router.get("/:id/checkNonOpenPosts", auth.can("view group"), (req, res) => {
2512
- var PostsByNotOpen = models.Post.scope("not_open");
2513
- PostsByNotOpen.count({ where: { group_id: req.params.id } })
2514
- .then(function (count) {
2515
- res.send({ hasNonOpenPosts: count != 0 });
2516
- })
2517
- .catch(function (error) {
2518
- sendGroupOrError(res, null, "checkNonOpenPosts", req.user, error);
2519
- });
2520
- });
2521
- router.get("/:id/configuration", auth.can("view group"), (req, res) => {
2522
- models.Group.findOne({
2523
- where: {
2524
- id: req.params.id,
2525
- },
2526
- attributes: ["id", "configuration"],
2527
- })
2528
- .then((group) => {
2529
- res.send(group.configuration);
2530
- })
2531
- .catch((error) => {
2532
- sendGroupOrError(res, null, "configuration", req.user, error);
2533
- });
2534
- });
2535
- const addVideosToGroup = (group, done) => {
2536
- models.Video.findAll({
2537
- attributes: ["id", "formats", "viewable", "created_at", "public_meta"],
2538
- include: [
2539
- {
2540
- model: models.Image,
2541
- as: "VideoImages",
2542
- attributes: ["formats", "created_at"],
2543
- required: false,
2544
- },
2545
- {
2546
- model: models.Group,
2547
- where: {
2548
- id: group.id,
2549
- },
2550
- as: "GroupLogoVideos",
2551
- required: true,
2552
- attributes: ["id"],
2553
- },
2554
- ],
2555
- order: [[{ model: models.Image, as: "VideoImages" }, "created_at", "asc"]],
2556
- })
2557
- .then((videos) => {
2558
- group.dataValues.GroupLogoVideos = _.orderBy(videos, ["created_at"], ["desc"]);
2559
- done();
2560
- })
2561
- .catch((error) => {
2562
- done(error);
2563
- });
2564
- };
2565
- router.get("/:groupFolderId/groupFolder", auth.can("view group"), function (req, res) {
2566
- if (isValidDbId(req.params.groupFolderId)) {
2567
- getGroupFolder(req, function (error, groupFolder) {
2568
- if (error) {
2569
- log.error("Could not get groupFolder", {
2570
- err: error,
2571
- groupFolderId: req.params.groupFolderId,
2572
- user: req.user ? toJson(req.user.simple()) : null,
2573
- });
2574
- res.sendStatus(500);
2575
- }
2576
- else if (groupFolder) {
2577
- res.send({ group: groupFolder });
2578
- }
2579
- else {
2580
- res.sendStatus(404);
2581
- }
2582
- });
2583
- }
2584
- else {
2585
- res.sendStatus(404);
2586
- }
2587
- });
2588
- router.get("/:id", auth.can("view group"), function (req, res) {
2589
- if (isValidDbId(req.params.id)) {
2590
- models.Group.findOne({
2591
- where: { id: req.params.id },
2592
- attributes: models.Group.defaultAttributesPublic,
2593
- order: [
2594
- [{ model: models.Image, as: "GroupLogoImages" }, "created_at", "asc"],
2595
- [{ model: models.Image, as: "GroupHeaderImages" }, "created_at", "asc"],
2596
- [
2597
- { model: models.Category },
2598
- { model: models.Image, as: "CategoryIconImages" },
2599
- "updated_at",
2600
- "asc",
2601
- ],
2602
- [{ model: models.Category }, "name", "asc"],
2603
- [
2604
- { model: models.Community },
2605
- { model: models.Image, as: "CommunityHeaderImages" },
2606
- "created_at",
2607
- "asc",
2608
- ],
2609
- ],
2610
- include: [
2611
- {
2612
- model: models.Community,
2613
- attributes: [
2614
- "id",
2615
- "theme_id",
2616
- "name",
2617
- "access",
2618
- "google_analytics_code",
2619
- "configuration",
2620
- "language",
2621
- "only_admins_can_create_groups",
2622
- ],
2623
- include: [
2624
- {
2625
- model: models.Domain,
2626
- attributes: ["id", "theme_id", "name", "configuration"],
2627
- },
2628
- {
2629
- model: models.Image,
2630
- as: "CommunityHeaderImages",
2631
- attributes: models.Image.defaultAttributesPublic,
2632
- required: false,
2633
- },
2634
- ],
2635
- },
2636
- {
2637
- model: models.Group,
2638
- required: false,
2639
- as: "GroupFolder",
2640
- attributes: ["id", "name"],
2641
- },
2642
- {
2643
- model: models.Category,
2644
- required: false,
2645
- include: [
2646
- {
2647
- model: models.Image,
2648
- required: false,
2649
- as: "CategoryIconImages",
2650
- attributes: models.Image.defaultAttributesPublic,
2651
- order: [
2652
- [
2653
- { model: models.Image, as: "CategoryIconImages" },
2654
- "updated_at",
2655
- "asc",
2656
- ],
2657
- ],
2658
- },
2659
- ],
2660
- },
2661
- {
2662
- model: models.Image,
2663
- as: "GroupLogoImages",
2664
- attributes: models.Image.defaultAttributesPublic,
2665
- required: false,
2666
- },
2667
- {
2668
- model: models.Image,
2669
- as: "GroupHeaderImages",
2670
- attributes: models.Image.defaultAttributesPublic,
2671
- required: false,
2672
- },
2673
- ],
2674
- })
2675
- .then(function (group) {
2676
- if (group) {
2677
- addVideosToGroup(group, (error) => {
2678
- if (error) {
2679
- sendGroupOrError(res, null, "count_posts", req.user, error);
2680
- }
2681
- else {
2682
- log.info("Group Viewed", {
2683
- id: group.id,
2684
- userId: req.user ? req.user.id : -1,
2685
- });
2686
- var PostsByNotOpen = models.Post.scope("not_open");
2687
- PostsByNotOpen.count({ where: { group_id: req.params.id } })
2688
- .then(function (count) {
2689
- res.send({ group: group, hasNonOpenPosts: count != 0 });
2690
- })
2691
- .catch(function (error) {
2692
- sendGroupOrError(res, null, "count_posts", req.user, error);
2693
- });
2694
- }
2695
- });
2696
- }
2697
- else {
2698
- sendGroupOrError(res, req.params.id, "view", req.user, "Not found", 404);
2699
- }
2700
- return null;
2701
- })
2702
- .catch(function (error) {
2703
- sendGroupOrError(res, null, "view", req.user, error);
2704
- });
2705
- }
2706
- else {
2707
- res.sendStatus(404);
2708
- }
2709
- });
2710
- const allowedTextTypesForGroup = [
2711
- "alternativeTextForNewIdeaButton",
2712
- "alternativeTextForNewIdeaButtonClosed",
2713
- "alternativeTextForNewIdeaButtonHeader",
2714
- "alternativeTextForNewIdeaSaveButton",
2715
- "customCategoryQuestionText",
2716
- "alternativePointForHeader",
2717
- "customThankYouTextNewPosts",
2718
- "customTitleQuestionText",
2719
- "customFilterText",
2720
- "customTabTitleNewLocation",
2721
- "alternativePointAgainstHeader",
2722
- "alternativePointForLabel",
2723
- "alternativePointAgainstLabel",
2724
- "customAdminCommentsTitle",
2725
- "urlToReviewActionText",
2726
- "aoiWelcomeMessage",
2727
- "aoiWelcomeHtml",
2728
- "aoiQuestionText",
2729
- "aoiAnswerText",
2730
- ];
2731
- router.get("/:id/translatedText", auth.can("view group"), function (req, res) {
2732
- if (req.query.textType.indexOf("group") > -1 ||
2733
- allowedTextTypesForGroup.indexOf(req.query.textType) > -1) {
2734
- models.Group.findOne({
2735
- where: {
2736
- id: req.params.id,
2737
- },
2738
- attributes: ["id", "name", "objectives", "configuration"],
2739
- })
2740
- .then(function (group) {
2741
- if (group) {
2742
- models.AcTranslationCache.getTranslation(req, group, function (error, translation) {
2743
- if (error) {
2744
- sendGroupOrError(res, req.params.id, "translated", req.user, error, 500);
2745
- }
2746
- else {
2747
- res.send(translation);
2748
- }
2749
- });
2750
- log.info("Group translatedTitle", { context: "translated" });
2751
- }
2752
- else {
2753
- sendGroupOrError(res, req.params.id, "translated", req.user, "Not found", 404);
2754
- }
2755
- })
2756
- .catch(function (error) {
2757
- sendGroupOrError(res, null, "translated", req.user, error);
2758
- });
2759
- }
2760
- else {
2761
- sendGroupOrError(res, req.params.id, "translated", req.user, "Wrong textType", 401);
2762
- }
2763
- });
2764
- router.get("/:id/translatedSurveyQuestions", auth.can("view group"), function (req, res) {
2765
- const targetLanguage = req.query.targetLanguage;
2766
- models.AcTranslationCache.getSurveyQuestionTranslations(req.params.id, targetLanguage, (error, translations) => {
2767
- if (error) {
2768
- sendGroupOrError(res, req.params.id, "translatedSurveyQuestions", req.user, error, 500);
2769
- }
2770
- else {
2771
- res.send(translations);
2772
- }
2773
- });
2774
- });
2775
- router.get("/:id/translatedRegistrationQuestions", auth.can("view group"), function (req, res) {
2776
- const targetLanguage = req.query.targetLanguage;
2777
- models.AcTranslationCache.getRegistrationQuestionTranslations(req.params.id, targetLanguage, (error, translations) => {
2778
- if (error) {
2779
- sendGroupOrError(res, req.params.id, "translatedRegistrationQuestions", req.user, error, 500);
2780
- }
2781
- else {
2782
- res.send(translations);
2783
- }
2784
- });
2785
- });
2786
- router.get("/:id/search/:term", auth.can("view group"), function (req, res) {
2787
- log.info("Group Search", {
2788
- groupId: req.params.id,
2789
- context: "view",
2790
- user: toJson(req.user),
2791
- });
2792
- models.Post.search(req.params.term, req.params.id, models.Category).then(function (posts) {
2793
- posts = _.reject(posts, function (post) {
2794
- return post.deleted == true;
2795
- });
2796
- res.send({
2797
- posts: posts,
2798
- totalPostsCount: posts.length,
2799
- });
2800
- });
2801
- });
2802
- var getPostsWithAllFromIds = function (postsWithIds, postOrder, done) {
2803
- var collectedIds = _.map(postsWithIds, function (post) {
2804
- return post.id;
2805
- });
2806
- let posts;
2807
- let videos;
2808
- async.parallel([
2809
- (parallelCallback) => {
2810
- models.Post.findAll({
2811
- where: {
2812
- id: {
2813
- $in: collectedIds,
2814
- },
2815
- },
2816
- attributes: [
2817
- "id",
2818
- "name",
2819
- "description",
2820
- "public_data",
2821
- "status",
2822
- "content_type",
2823
- "official_status",
2824
- "counter_endorsements_up",
2825
- "cover_media_type",
2826
- "counter_endorsements_down",
2827
- "group_id",
2828
- "language",
2829
- "counter_points",
2830
- "counter_flags",
2831
- "location",
2832
- "created_at",
2833
- "category_id",
2834
- ],
2835
- order: [models.sequelize.literal(postOrder)],
2836
- include: [
2837
- {
2838
- model: models.Category,
2839
- attributes: { exclude: ["ip_address", "user_agent"] },
2840
- required: false,
2841
- include: [
2842
- {
2843
- model: models.Image,
2844
- required: false,
2845
- attributes: models.Image.defaultAttributesPublic,
2846
- as: "CategoryIconImages",
2847
- },
2848
- ],
2849
- },
2850
- {
2851
- model: models.Audio,
2852
- required: false,
2853
- attributes: ["id", "formats", "updated_at", "listenable"],
2854
- as: "PostAudios",
2855
- },
2856
- {
2857
- model: models.User,
2858
- required: false,
2859
- attributes: models.User.defaultAttributesWithSocialMediaPublic,
2860
- include: [
2861
- {
2862
- model: models.Image,
2863
- as: "UserProfileImages",
2864
- attributes: ["id", "formats", "updated_at"],
2865
- required: false,
2866
- },
2867
- ],
2868
- },
2869
- {
2870
- model: models.Group,
2871
- required: true,
2872
- attributes: ["id", "configuration", "name", "theme_id", "access"],
2873
- include: [
2874
- {
2875
- model: models.Category,
2876
- required: false,
2877
- },
2878
- {
2879
- model: models.Community,
2880
- attributes: [
2881
- "id",
2882
- "name",
2883
- "theme_id",
2884
- "access",
2885
- "google_analytics_code",
2886
- "configuration",
2887
- "only_admins_can_create_groups",
2888
- ],
2889
- required: true,
2890
- },
2891
- ],
2892
- },
2893
- {
2894
- model: models.Image,
2895
- attributes: models.Image.defaultAttributesPublic,
2896
- as: "PostHeaderImages",
2897
- required: false,
2898
- },
2899
- ],
2900
- })
2901
- .then(function (postsIn) {
2902
- posts = postsIn;
2903
- log.info("FINISHED POSTS A");
2904
- posts.forEach((post) => {
2905
- if (post.PostHeaderImages) {
2906
- post.PostHeaderImages = _.orderBy(post.PostHeaderImages, ["updated_at"], ["asc"]);
2907
- }
2908
- if (post.Category && post.Category.CategoryIconImages) {
2909
- post.Category.CategoryIconImages = _.orderBy(post.Category.CategoryIconImages, ["updated_at"], ["asc"]);
2910
- }
2911
- if (post.PostAudios) {
2912
- post.PostAudios = _.orderBy(post.PostAudios, ["updated_at"], ["desc"]);
2913
- }
2914
- if (post.Group && post.Group.Categories) {
2915
- post.Group.Categories = _.orderBy(post.Group.Categories, ["name"], ["asc"]);
2916
- }
2917
- });
2918
- parallelCallback();
2919
- })
2920
- .catch(function (error) {
2921
- parallelCallback(error);
2922
- });
2923
- },
2924
- (parallelCallback) => {
2925
- models.Post.getVideosForPosts(collectedIds, (error, videosIn) => {
2926
- log.info("GOT VIDEOS 1");
2927
- if (error) {
2928
- parallelCallback(error);
2929
- }
2930
- else {
2931
- videos = videosIn;
2932
- parallelCallback();
2933
- }
2934
- });
2935
- },
2936
- ], (error) => {
2937
- if (error) {
2938
- done(error);
2939
- }
2940
- else {
2941
- if (videos && videos.length > 0) {
2942
- log.info("GOT VIDEOS 2");
2943
- models.Post.addVideosToAllPosts(posts, videos);
2944
- }
2945
- else if (!videos) {
2946
- log.error("No videos for getVideosForPosts");
2947
- }
2948
- log.info("FINISHED POSTS B");
2949
- done(null, posts);
2950
- }
2951
- });
2952
- };
2953
- router.get("/:id/posts/:filter/:categoryId/:status?", auth.can("view group"), function (req, res) {
2954
- const redisKey = `cache:posts:${req.params.id}:${req.params.filter}:${req.params.categoryId}:${req.params.status}:${req.query.offset}:${req.query.randomSeed}`;
2955
- req.redisClient
2956
- .get(redisKey)
2957
- .then((postsInfo) => {
2958
- if (postsInfo) {
2959
- res.send(JSON.parse(postsInfo));
2960
- }
2961
- else {
2962
- models.Group.findOne({
2963
- where: {
2964
- id: req.params.id,
2965
- },
2966
- attributes: ["id", "configuration"],
2967
- })
2968
- .then((group) => {
2969
- var where = { group_id: req.params.id, deleted: false };
2970
- let attributes = [
2971
- "id",
2972
- "status",
2973
- "name",
2974
- "official_status",
2975
- "language",
2976
- "counter_endorsements_up",
2977
- "counter_endorsements_down",
2978
- "created_at",
2979
- ];
2980
- const includes = [];
2981
- var postOrder = "(counter_endorsements_up-counter_endorsements_down) DESC";
2982
- if (req.params.filter === "newest") {
2983
- postOrder = "created_at DESC";
2984
- }
2985
- else if (req.params.filter === "most_debated") {
2986
- postOrder = "counter_points DESC";
2987
- }
2988
- else if (req.params.filter === "random") {
2989
- postOrder = "created_at DESC";
2990
- }
2991
- else if (req.params.filter === "oldest") {
2992
- postOrder = "created_at ASC";
2993
- }
2994
- else if (req.params.filter === "alphabetical") {
2995
- postOrder = "name ASC";
2996
- }
2997
- let postOrderFinal = [models.sequelize.literal(postOrder)];
2998
- let seqGroup = null;
2999
- let ratingOrderNeeded = false;
3000
- let limit = 20;
3001
- var offset = 0;
3002
- if (req.query.offset) {
3003
- offset = parseInt(req.query.offset);
3004
- }
3005
- let ratingOffset = offset;
3006
- const ratingsPostLookup = {};
3007
- if (req.params.filter === "top" &&
3008
- group.configuration &&
3009
- group.configuration.customRatings != null &&
3010
- group.configuration.customRatings.length > 0) {
3011
- const attrIncludes = [];
3012
- attrIncludes.push([
3013
- models.sequelize.literal(`(
3014
- SELECT AVG(value)
3015
- FROM ratings AS rating
3016
- WHERE
3017
- rating.post_id = "Post".id
3018
- )`),
3019
- "RatingAverage",
3020
- ]);
3021
- attrIncludes.push([
3022
- models.sequelize.literal(`(
3023
- SELECT COUNT(*)
3024
- FROM ratings AS rating
3025
- WHERE
3026
- rating.post_id = "Post".id
3027
- )`),
3028
- "RatingCount",
3029
- ]);
3030
- //TODO: Include also just the attributes from above
3031
- attributes = {
3032
- include: attrIncludes,
3033
- };
3034
- //postOrderFinal = models.sequelize.literal("RatingAverage ASC");
3035
- ratingOrderNeeded = true;
3036
- //TODO: Get postgres ordering working with a count limit ORDER BY flag CASE
3037
- limit = 1500;
3038
- offset = 0;
3039
- }
3040
- if (req.params.categoryId != "null") {
3041
- where["category_id"] = req.params.categoryId;
3042
- }
3043
- log.info("Posts", {
3044
- gId: req.params.id,
3045
- f: req.params.filter,
3046
- cId: req.params.categoryId,
3047
- uId: req.user ? req.user.id : -1,
3048
- });
3049
- if (["open", "failed", "successful", "in_progress"].indexOf(req.params.status) > -1) {
3050
- var PostsByStatus = models.Post.scope(req.params.status);
3051
- PostsByStatus.findAndCountAll({
3052
- where: where,
3053
- attributes: attributes,
3054
- include: includes,
3055
- group: seqGroup,
3056
- order: postOrderFinal,
3057
- limit: limit,
3058
- offset: offset,
3059
- })
3060
- .then(function (postResults) {
3061
- log.info("Posts 2");
3062
- const posts = postResults.rows;
3063
- var totalPostsCount = postResults.count;
3064
- var postRows = posts;
3065
- if (req.params.filter === "random" &&
3066
- req.query.randomSeed &&
3067
- postRows.length > 0) {
3068
- postRows = seededShuffle(postRows, req.query.randomSeed);
3069
- }
3070
- if (ratingOrderNeeded) {
3071
- postRows = _.forEach(postRows, (post) => {
3072
- if (post.dataValues.RatingCount &&
3073
- post.dataValues.RatingAverage) {
3074
- const ratingCount = parseInt(post.dataValues.RatingCount);
3075
- const ratingAverage = parseFloat(post.dataValues.RatingAverage);
3076
- // More than one round of full ratings for the rating to count towards top rating calc
3077
- if (ratingCount >
3078
- group.configuration.customRatings.length) {
3079
- ratingsPostLookup[post.dataValues.id] =
3080
- ratingAverage;
3081
- }
3082
- else {
3083
- ratingsPostLookup[post.dataValues.id] = 0.0;
3084
- }
3085
- }
3086
- else {
3087
- ratingsPostLookup[post.dataValues.id] = 0.0;
3088
- }
3089
- });
3090
- postRows = _.orderBy(postRows, [
3091
- (post) => {
3092
- return ratingsPostLookup[post.dataValues.id];
3093
- },
3094
- ], ["desc"]);
3095
- if (ratingOffset) {
3096
- postRows = _.drop(postRows, ratingOffset);
3097
- }
3098
- if (postRows.length > 20) {
3099
- postRows = _.dropRight(postRows, postRows.length - 20);
3100
- }
3101
- totalPostsCount = postResults.rows.length;
3102
- }
3103
- log.info("Posts 3");
3104
- getPostsWithAllFromIds(postRows, postOrder, function (error, finalRows) {
3105
- log.info("Posts 4");
3106
- if (error) {
3107
- log.error("Error getting group", { err: error });
3108
- res.sendStatus(500);
3109
- }
3110
- else {
3111
- if (req.params.filter === "random" &&
3112
- req.query.randomSeed &&
3113
- finalRows &&
3114
- finalRows.length > 0) {
3115
- finalRows = seededShuffle(finalRows, req.query.randomSeed);
3116
- }
3117
- else if (ratingOrderNeeded) {
3118
- finalRows = _.orderBy(finalRows, [
3119
- (post) => {
3120
- return ratingsPostLookup[post.dataValues.id];
3121
- },
3122
- ], ["desc"]);
3123
- }
3124
- models.Post.setOrganizationUsersForPosts(finalRows, (error) => {
3125
- log.info("Posts 2");
3126
- if (error) {
3127
- log.error("Error getting group", {
3128
- err: error,
3129
- });
3130
- res.sendStatus(500);
3131
- }
3132
- else {
3133
- const postsOut = {
3134
- posts: finalRows,
3135
- totalPostsCount: totalPostsCount,
3136
- };
3137
- req.redisClient.setEx(redisKey, process.env.POSTS_CACHE_TTL
3138
- ? parseInt(process.env.POSTS_CACHE_TTL)
3139
- : 3, JSON.stringify(postsOut));
3140
- res.send(postsOut);
3141
- }
3142
- });
3143
- }
3144
- });
3145
- })
3146
- .catch(function (error) {
3147
- log.error("Error getting group", { err: error });
3148
- res.sendStatus(500);
3149
- });
3150
- }
3151
- else {
3152
- log.error("Cant find status", { status: req.params.status });
3153
- res.sendStatus(404);
3154
- }
3155
- })
3156
- .catch((errorGroup) => {
3157
- sendGroupOrError(res, null, "getPostsFromGroup Group.find", req.user, errorGroup);
3158
- });
3159
- }
3160
- })
3161
- .catch((error) => {
3162
- sendGroupOrError(res, null, "getPostsFromGroup", req.user, error);
3163
- });
3164
- });
3165
- router.get("/:id/categories", auth.can("view group"), function (req, res) {
3166
- models.Category.findAll({
3167
- where: { group_id: req.params.id },
3168
- limit: 20,
3169
- })
3170
- .then(function (categories) {
3171
- if (categories) {
3172
- log.info("Group Categories Viewed", {
3173
- group: req.params.id,
3174
- context: "view",
3175
- user: toJson(req.user),
3176
- });
3177
- res.send(categories);
3178
- }
3179
- else {
3180
- sendGroupOrError(res, req.params.id, "view", req.user, "Not found", 404);
3181
- }
3182
- })
3183
- .catch(function (error) {
3184
- sendGroupOrError(res, null, "view categories", req.user, error);
3185
- });
3186
- });
3187
- router.get("/:id/post_locations", auth.can("view group"), function (req, res) {
3188
- models.Post.findAll({
3189
- where: {
3190
- location: {
3191
- $ne: null,
3192
- },
3193
- group_id: req.params.id,
3194
- },
3195
- attributes: models.Post.defaultAttributesPublic,
3196
- order: [
3197
- [{ model: models.Image, as: "PostHeaderImages" }, "updated_at", "asc"],
3198
- ],
3199
- include: [
3200
- {
3201
- model: models.Image,
3202
- as: "PostHeaderImages",
3203
- attributes: models.Image.defaultAttributesPublic,
3204
- required: false,
3205
- },
3206
- {
3207
- model: models.Group,
3208
- attributes: ["id", "configuration"],
3209
- required: true,
3210
- },
3211
- ],
3212
- select: ["id", "name", "location"],
3213
- })
3214
- .then(function (posts) {
3215
- if (posts) {
3216
- log.info("Group Post Locations Viewed", {
3217
- communityId: req.params.id,
3218
- userId: req.user ? req.user.id : -1,
3219
- });
3220
- var collectedIds = _.map(posts, function (post) {
3221
- return post.id;
3222
- });
3223
- models.Post.getVideosForPosts(collectedIds, (error, videos) => {
3224
- if (error) {
3225
- sendGroupOrError(res, null, "view post locations", req.user, "Not found", 404);
3226
- }
3227
- else {
3228
- if (videos.length > 0) {
3229
- models.Post.addVideosToAllPosts(posts, videos);
3230
- }
3231
- res.send(posts);
3232
- }
3233
- });
3234
- }
3235
- else {
3236
- sendGroupOrError(res, null, "view post locations", req.user, "Not found", 404);
3237
- }
3238
- })
3239
- .catch(function (error) {
3240
- sendGroupOrError(res, null, "view post locations", req.user, error);
3241
- });
3242
- });
3243
- router.get("/:id/categories_count/:tabName", auth.can("view group"), function (req, res) {
3244
- var categoriesCount, allPostCount;
3245
- var status = null;
3246
- if (req.params.tabName === "failed") {
3247
- status = -2;
3248
- }
3249
- else if (req.params.tabName === "open") {
3250
- status = 0;
3251
- }
3252
- else if (req.params.tabName === "in_progress") {
3253
- status = -1;
3254
- }
3255
- else if (req.params.tabName === "successful") {
3256
- status = 2;
3257
- }
3258
- if (status !== null) {
3259
- async.parallel([
3260
- function (parallelCallback) {
3261
- models.Post.count({
3262
- attributes: ["category_id"],
3263
- where: {
3264
- group_id: req.params.id,
3265
- official_status: status,
3266
- },
3267
- include: [
3268
- {
3269
- model: models.Category,
3270
- },
3271
- ],
3272
- group: ["category_id"],
3273
- })
3274
- .then(function (results) {
3275
- categoriesCount = results;
3276
- parallelCallback();
3277
- })
3278
- .catch(function (error) {
3279
- parallelCallback(error);
3280
- });
3281
- },
3282
- function (parallelCallback) {
3283
- models.Post.count({
3284
- where: {
3285
- group_id: req.params.id,
3286
- official_status: status,
3287
- },
3288
- })
3289
- .then(function (count) {
3290
- allPostCount = count;
3291
- parallelCallback();
3292
- })
3293
- .catch(function (error) {
3294
- parallelCallback(error);
3295
- });
3296
- },
3297
- ], function (error) {
3298
- if (error) {
3299
- sendGroupOrError(res, null, "categories_count", req.user, error);
3300
- }
3301
- else {
3302
- res.send({
3303
- categoriesCount: categoriesCount,
3304
- allPostCount: allPostCount,
3305
- });
3306
- }
3307
- });
3308
- }
3309
- else {
3310
- sendGroupOrError(res, null, "categories_count", req.user, "Cant find status for posts");
3311
- }
3312
- });
3313
- router.put("/:id/:groupId/mergeWithGroup", auth.can("edit post"), function (req, res) {
3314
- auth.authNeedsGroupAdminForCreate({ id: req.params.groupId }, req, function (error, isAuthorized) {
3315
- if (isAuthorized) {
3316
- var inGroup, outGroup, post, outCommunityId, outDomainId;
3317
- async.series([
3318
- function (callback) {
3319
- models.Group.findOne({
3320
- where: {
3321
- id: req.params.id,
3322
- },
3323
- include: [
3324
- {
3325
- model: models.Community,
3326
- required: true,
3327
- include: [
3328
- {
3329
- model: models.Domain,
3330
- required: true,
3331
- attributes: models.Domain.defaultAttributesPublic,
3332
- },
3333
- ],
3334
- },
3335
- ],
3336
- })
3337
- .then(function (group) {
3338
- inGroup = groupIn;
3339
- callback();
3340
- })
3341
- .catch(function (error) {
3342
- callback(error);
3343
- });
3344
- },
3345
- function (callback) {
3346
- models.Group.findOne({
3347
- where: {
3348
- id: req.params.groupId,
3349
- },
3350
- include: [
3351
- {
3352
- model: models.Community,
3353
- required: true,
3354
- include: [
3355
- {
3356
- model: models.Domain,
3357
- required: true,
3358
- attributes: models.Domain.defaultAttributesPublic,
3359
- },
3360
- ],
3361
- },
3362
- ],
3363
- })
3364
- .then(function (group) {
3365
- outGroup = group;
3366
- outCommunityId = group.Community.id;
3367
- outDomainId = group.Community.Domain.id;
3368
- callback();
3369
- })
3370
- .catch(function (error) {
3371
- callback(error);
3372
- });
3373
- },
3374
- function (callback) {
3375
- models.Post.findAll({
3376
- where: {
3377
- group_id: inGroup.id,
3378
- },
3379
- })
3380
- .then(function (posts) {
3381
- async.eachSeries(posts, function (post, seriesCallback) {
3382
- post.set("group_id", outGroup.id);
3383
- post.save().then(function (results) {
3384
- console.log("Have changed group id");
3385
- models.AcActivity.findAll({
3386
- where: {
3387
- post_id: post.id,
3388
- },
3389
- })
3390
- .then(function (activities) {
3391
- async.eachSeries(activities, function (activity, innerSeriesCallback) {
3392
- activity.set("group_id", outGroup.id);
3393
- activity.set("community_id", outCommunityId);
3394
- activity.set("domain_id", outDomainId);
3395
- activity.save().then(function (results) {
3396
- console.log("Have changed group and all: " +
3397
- activity.id);
3398
- innerSeriesCallback();
3399
- });
3400
- }, function (error) {
3401
- seriesCallback(error);
3402
- });
3403
- })
3404
- .catch(function (error) {
3405
- seriesCallback(error);
3406
- });
3407
- }, function (error) {
3408
- callback(error);
3409
- });
3410
- });
3411
- })
3412
- .catch(function (error) {
3413
- callback(error);
3414
- });
3415
- },
3416
- ], function (error) {
3417
- if (error) {
3418
- log.error("Merge with group", {
3419
- groupId: req.params.id,
3420
- groupToId: req.params.groupId,
3421
- });
3422
- res.sendStatus(500);
3423
- }
3424
- else {
3425
- log.info("Merge with group", {
3426
- groupId: req.params.id,
3427
- groupToId: req.params.groupId,
3428
- });
3429
- res.sendStatus(200);
3430
- }
3431
- });
3432
- }
3433
- else {
3434
- log.error("Merge with group", {
3435
- groupId: req.params.id,
3436
- groupToId: req.params.groupId,
3437
- });
3438
- res.sendStatus(401);
3439
- }
3440
- });
3441
- });
3442
- // Moderation
3443
- router.delete("/:groupId/:itemId/:itemType/:actionType/process_one_moderation_item", auth.can("edit group"), (req, res) => {
3444
- performSingleModerationAction(req, res, {
3445
- groupId: req.params.groupId,
3446
- itemId: req.params.itemId,
3447
- itemType: req.params.itemType,
3448
- actionType: req.params.actionType,
3449
- });
3450
- });
3451
- router.delete("/:groupId/:actionType/process_many_moderation_item", auth.can("edit group"), (req, res) => {
3452
- queue.add("process-moderation", {
3453
- type: "perform-many-moderation-actions",
3454
- items: req.body.items,
3455
- actionType: req.params.actionType,
3456
- groupId: req.params.groupId,
3457
- }, "critical");
3458
- res.send({});
3459
- });
3460
- router.get("/:groupId/flagged_content", auth.can("edit group"), (req, res) => {
3461
- getAllModeratedItemsByGroup({ groupId: req.params.groupId }, (error, items) => {
3462
- if (error) {
3463
- log.error("Error getting items for moderation", { error });
3464
- res.sendStatus(500);
3465
- }
3466
- else {
3467
- res.send(items);
3468
- }
3469
- });
3470
- });
3471
- router.get("/:groupId/moderate_all_content", auth.can("edit group"), (req, res) => {
3472
- getAllModeratedItemsByGroup({ groupId: req.params.groupId, allContent: true }, (error, items) => {
3473
- if (error) {
3474
- log.error("Error getting items for moderation", { error });
3475
- res.sendStatus(500);
3476
- }
3477
- else {
3478
- res.send(items);
3479
- }
3480
- });
3481
- });
3482
- router.get("/:groupId/flagged_content_count", auth.can("edit group"), (req, res) => {
3483
- countAllModeratedItemsByGroup({ groupId: req.params.groupId }, (error, count) => {
3484
- if (error) {
3485
- log.error("Error getting items for moderation", { error });
3486
- res.sendStatus(500);
3487
- }
3488
- else {
3489
- res.send({ count });
3490
- }
3491
- });
3492
- });
3493
- // CAMPAIGNS
3494
- router.post("/:id/campaignCreateAndStart", auth.can("edit group"), (req, res) => {
3495
- models.AcCampaign.createAndSendCampaign(req.body, (error) => {
3496
- if (error) {
3497
- log.error("Group createCampaign error", {
3498
- context: "campaignCreateAndStart",
3499
- params: req.body,
3500
- error,
3501
- });
3502
- res.sendStatus(500);
3503
- }
3504
- else {
3505
- log.info("Group createCampaign completed", {
3506
- context: "campaignCreateAndStart",
3507
- });
3508
- res.sendStatus(200);
3509
- }
3510
- });
3511
- });
3512
- router.get("/:groupId/:jobId/getCampaignSendStatus", auth.can("edit group"), function (req, res) {
3513
- models.AcCampaign.getSendStatus(req.params.jobId, (error, results) => {
3514
- if (error) {
3515
- log.error("Group createCampaign error", {
3516
- context: "getCampaignSendStatus",
3517
- error,
3518
- });
3519
- res.sendStatus(500);
3520
- }
3521
- else {
3522
- log.info("Group getCampaignSendStatus completed", {
3523
- context: "getCampaignSendStatus",
3524
- });
3525
- res.sendresults;
3526
- }
3527
- });
3528
- });
3529
- router.get("/:id/getCampaigns", auth.can("edit group"), (req, res) => {
3530
- models.AcCampaign.find({
3531
- where: {
3532
- group_id: req.params.id,
3533
- },
3534
- })
3535
- .then((campaigns) => {
3536
- res.send(campaigns);
3537
- })
3538
- .catch((error) => {
3539
- log.info("Group createCampaign error", {
3540
- context: "createCampaign",
3541
- params: req.body,
3542
- error,
3543
- });
3544
- res.sendStatus(500);
3545
- });
3546
- });
3547
- // LISTS
3548
- router.get("/:id/getList", auth.can("edit group"), (req, res) => {
3549
- models.AcList.getList(req.params.id, (error, results) => {
3550
- if (error) {
3551
- log.error("Group getList error", { context: "getList", error });
3552
- res.sendStatus(500);
3553
- }
3554
- else {
3555
- log.info("Group getList completed", { context: "getList" });
3556
- res.send(results);
3557
- }
3558
- });
3559
- });
3560
- router.put("/:id/:listId/addListUsers", auth.can("edit group"), (req, res) => {
3561
- models.AcList.addListUsers(req.params.listId, req.body, (error, results) => {
3562
- if (error) {
3563
- log.error("Group addListUsers error", { context: "addListUsers", error });
3564
- res.sendStatus(500);
3565
- }
3566
- else {
3567
- log.info("Group addListUsers completed", { context: "addListUsers" });
3568
- res.send(results);
3569
- }
3570
- });
3571
- });
3572
- router.get("/:id/:listId/getListUsers", auth.can("edit group"), (req, res) => {
3573
- models.AcListUser.find({
3574
- where: {
3575
- ac_list_id: req.params.listId,
3576
- },
3577
- })
3578
- .then((listUsers) => {
3579
- res.send(listUsers);
3580
- })
3581
- .catch((error) => {
3582
- log.error("Group getListUsers error", {
3583
- context: "createCampaign",
3584
- error,
3585
- });
3586
- res.sendStatus(500);
3587
- });
3588
- });
3589
- router.post("/:id/marketingTrackingOpen", auth.can("view group"), (req, res) => {
3590
- if (req.body &&
3591
- req.body.originalQueryParameters &&
3592
- req.body.originalQueryParameters.yu) {
3593
- models.AcCampaign.updateCampaignAndUser(req.body.originalQueryParameters, "openCount", (error) => {
3594
- if (error) {
3595
- log.error("Group marketingTracking error", {
3596
- context: "marketingTracking",
3597
- params: req.body,
3598
- error,
3599
- });
3600
- res.sendStatus(500);
3601
- }
3602
- else {
3603
- log.info("Group marketingTracking marketing completed", {
3604
- context: "marketingTracking",
3605
- params: req.body,
3606
- });
3607
- res.sendStatus(200);
3608
- }
3609
- });
3610
- }
3611
- else {
3612
- log.warn("Group marketingTracking no tracking parameters");
3613
- res.sendStatus(200);
3614
- }
3615
- });
3616
- router.post("/:id/triggerTrackingGoal", auth.can("view group"), (req, res) => {
3617
- if (req.body &&
3618
- req.body.originalQueryParameters &&
3619
- req.body.originalQueryParameters.yu) {
3620
- models.AcCampaign.updateCampaignAndUser(req.body.originalQueryParameters, "completeCount", (error) => {
3621
- if (error) {
3622
- log.error("Group triggerTrackingGoal error", {
3623
- context: "marketingTracking",
3624
- params: req.body,
3625
- error,
3626
- });
3627
- res.sendStatus(500);
3628
- }
3629
- else {
3630
- log.info("Group triggerTrackingGoal marketing completed", {
3631
- context: "triggerTrackingGoal",
3632
- params: req.body,
3633
- });
3634
- res.sendStatus(200);
3635
- }
3636
- });
3637
- }
3638
- else {
3639
- models.Group.findOne({
3640
- where: {
3641
- id: req.params.id,
3642
- },
3643
- attributes: ["id", "configuration"],
3644
- })
3645
- .then(function (group) {
3646
- if (group &&
3647
- group.configuration &&
3648
- group.configuration.externalGoalTriggerUrl) {
3649
- log.info("Group triggerTrackingGoal starting", {
3650
- context: "triggerTrackingGoal",
3651
- params: req.body,
3652
- group: group,
3653
- });
3654
- const options = {
3655
- url: group.configuration.externalGoalTriggerUrl,
3656
- qs: req.body,
3657
- };
3658
- request.get(options, (response, message) => {
3659
- if ((response && response.errno) ||
3660
- (message && message.statusCode !== 200)) {
3661
- log.info("Group triggerTrackingGoal error", {
3662
- context: "triggerTrackingGoal",
3663
- response: response,
3664
- message: message,
3665
- params: req.body,
3666
- group: group,
3667
- });
3668
- res.sendStatus(500);
3669
- }
3670
- else {
3671
- log.info("Group triggerTrackingGoal completed", {
3672
- context: "triggerTrackingGoal",
3673
- params: req.body,
3674
- group: group,
3675
- });
3676
- res.sendStatus(200);
3677
- }
3678
- });
3679
- //
3680
- }
3681
- else {
3682
- log.error("Error getting group for triggerTrackingGoal");
3683
- res.sendStatus(404);
3684
- }
3685
- })
3686
- .catch(function (error) {
3687
- log.error("Error getting group for triggerTrackingGoal", { error });
3688
- res.sendStatus(404);
3689
- });
3690
- }
3691
- });
3692
- router.put("/:id/:pointId/adminComment", auth.can("edit group"), function (req, res) {
3693
- if (!req.body.content) {
3694
- req.body.content = "";
3695
- }
3696
- models.Point.findOne({
3697
- where: {
3698
- id: req.params.pointId,
3699
- },
3700
- attributes: ["id", "public_data"],
3701
- })
3702
- .then(function (point) {
3703
- if (point) {
3704
- if (!point.public_data) {
3705
- point.set("public_data", {});
3706
- }
3707
- if (!point.public_data.admin_comment) {
3708
- point.set("public_data.admin_comment", {});
3709
- }
3710
- point.set("public_data.admin_comment", {
3711
- text: req.body.content,
3712
- userId: req.user.id,
3713
- userName: req.user.name,
3714
- createdAt: new Date(),
3715
- });
3716
- point
3717
- .save()
3718
- .then(() => {
3719
- res.send({ content: req.body.content });
3720
- })
3721
- .catch(function (error) {
3722
- log.error("Error adminComment", { error });
3723
- res.sendStatus(500);
3724
- });
3725
- }
3726
- else {
3727
- res.sendStatus(404);
3728
- }
3729
- })
3730
- .catch(function (error) {
3731
- log.error("Error adminComment", { error });
3732
- res.sendStatus(500);
3733
- });
3734
- });
3735
- router.get("/:groupId/survey", auth.can("view group"), (req, res) => {
3736
- models.Group.findOne({
3737
- where: { id: req.params.groupId },
3738
- order: [
3739
- [{ model: models.Image, as: "GroupLogoImages" }, "created_at", "asc"],
3740
- [{ model: models.Video, as: "GroupLogoVideos" }, "updated_at", "desc"],
3741
- [
3742
- { model: models.Video, as: "GroupLogoVideos" },
3743
- { model: models.Image, as: "VideoImages" },
3744
- "updated_at",
3745
- "asc",
3746
- ],
3747
- ],
3748
- attributes: ["id", "name", "configuration", "objectives"],
3749
- include: [
3750
- {
3751
- model: models.Community,
3752
- attributes: [
3753
- "id",
3754
- "theme_id",
3755
- "name",
3756
- "access",
3757
- "google_analytics_code",
3758
- "configuration",
3759
- "only_admins_can_create_groups",
3760
- ],
3761
- include: [
3762
- {
3763
- model: models.Domain,
3764
- attributes: ["id", "theme_id", "name"],
3765
- },
3766
- ],
3767
- },
3768
- {
3769
- model: models.Image,
3770
- as: "GroupLogoImages",
3771
- attributes: models.Image.defaultAttributesPublic,
3772
- required: false,
3773
- },
3774
- {
3775
- model: models.Video,
3776
- as: "GroupLogoVideos",
3777
- attributes: ["id", "formats", "viewable", "public_meta"],
3778
- required: false,
3779
- include: [
3780
- {
3781
- model: models.Image,
3782
- as: "VideoImages",
3783
- attributes: ["formats", "updated_at"],
3784
- required: false,
3785
- },
3786
- ],
3787
- },
3788
- ],
3789
- })
3790
- .then(function (group) {
3791
- if (group) {
3792
- log.info("Survey Group Viewed", {
3793
- groupId: group.id,
3794
- context: "view",
3795
- userId: req.user ? req.user.id : -1,
3796
- });
3797
- res.send({ surveyGroup: group });
3798
- }
3799
- else {
3800
- res.send({ error: "notFound" });
3801
- }
3802
- })
3803
- .catch(function (error) {
3804
- sendGroupOrError(res, null, "view survey", req.user, error);
3805
- });
3806
- });
3807
- router.post("/:groupId/survey", auth.can("view group"), (req, res) => {
3808
- let surveyGroup;
3809
- let loggedInUser = req.user;
3810
- async.series([
3811
- (seriesCallback) => {
3812
- models.Group.findOne({
3813
- where: { id: req.params.groupId },
3814
- attributes: ["id", "configuration"],
3815
- })
3816
- .then((group) => {
3817
- if (group) {
3818
- surveyGroup = group;
3819
- seriesCallback();
3820
- }
3821
- else {
3822
- seriesCallback("Group not found");
3823
- }
3824
- })
3825
- .catch((error) => {
3826
- seriesCallback(error);
3827
- });
3828
- },
3829
- (seriesCallback) => {
3830
- if (loggedInUser) {
3831
- seriesCallback();
3832
- }
3833
- else {
3834
- const anonSurveyEmail = "survey_group_" + surveyGroup.id + "_user_anonymous@citizens.is";
3835
- models.User.findOne({
3836
- where: {
3837
- email: anonSurveyEmail,
3838
- },
3839
- })
3840
- .then(function (existingUser) {
3841
- if (existingUser) {
3842
- loggedInUser = existingUser;
3843
- seriesCallback();
3844
- }
3845
- else {
3846
- var user = models.User.build({
3847
- email: anonSurveyEmail,
3848
- name: "Anonymous Survey User",
3849
- notifications_settings: models.AcNotification.anonymousNotificationSettings,
3850
- status: "active",
3851
- });
3852
- user.set("profile_data", {});
3853
- user.set("profile_data.isAnonymousUser", true);
3854
- user
3855
- .save()
3856
- .then(() => {
3857
- loggedInUser = user;
3858
- seriesCallback();
3859
- })
3860
- .catch((error) => {
3861
- seriesCallback(error);
3862
- });
3863
- }
3864
- })
3865
- .catch((error) => {
3866
- seriesCallback(error);
3867
- });
3868
- }
3869
- },
3870
- (seriesCallback) => {
3871
- const post = models.Post.build({
3872
- name: "Survey Response -" +
3873
- moment(new Date()).format("DD/MM/YYYY hh:mm:ss"),
3874
- description: "",
3875
- group_id: surveyGroup.id,
3876
- cover_media_type: "none",
3877
- user_id: loggedInUser.id,
3878
- status: "blocked",
3879
- counter_endorsements_up: 0,
3880
- content_type: models.Post.CONTENT_SURVEY,
3881
- user_agent: req.useragent.source,
3882
- ip_address: req.clientIp,
3883
- });
3884
- post.set("public_data", {});
3885
- if (req.body.structuredAnswers) {
3886
- post.set("public_data.structuredAnswersJson", req.body.structuredAnswers);
3887
- }
3888
- post
3889
- .save()
3890
- .then(() => {
3891
- log.info("Survey Post Created", {
3892
- postId: post.id,
3893
- context: "create",
3894
- });
3895
- post.updateAllExternalCounters(req, "up", "counter_posts", function () {
3896
- seriesCallback();
3897
- });
3898
- })
3899
- .catch((error) => {
3900
- seriesCallback(error);
3901
- });
3902
- },
3903
- ], (error) => {
3904
- if (error) {
3905
- sendGroupOrError(res, null, "post survey", req.user, error);
3906
- }
3907
- else {
3908
- res.sendStatus(200);
3909
- }
3910
- });
3911
- });
3912
- // WORD CLOUD
3913
- router.get("/:id/wordcloud", auth.can("edit group"), function (req, res) {
3914
- getFromAnalyticsApi(req, "wordclouds", "group", req.params.id, function (error, content) {
3915
- sendBackAnalyticsResultsOrError(req, res, error, content);
3916
- });
3917
- });
3918
- // SIMILARITIES
3919
- router.get("/:id/similarities_weights", auth.can("edit group"), function (req, res) {
3920
- getFromAnalyticsApi(req, "similarities_weights", "group", req.params.id, function (error, content) {
3921
- sendBackAnalyticsResultsOrError(req, res, error ? error : content.body ? null : "noBody", getParsedSimilaritiesContent(content));
3922
- });
3923
- });
3924
- // STATS
3925
- router.get("/:id/stats_posts", auth.can("edit group"), function (req, res) {
3926
- countModelRowsByTimePeriod(req, "stats_posts_" + req.params.id + "_group", models.Post, {}, getGroupIncludes(req.params.id), (error, results) => {
3927
- sendBackAnalyticsResultsOrError(req, res, error, results);
3928
- });
3929
- });
3930
- router.get("/:id/stats_points", auth.can("edit group"), function (req, res) {
3931
- countModelRowsByTimePeriod(req, "stats_points_" + req.params.id + "_group", models.Point, {}, getPointGroupIncludes(req.params.id), (error, results) => {
3932
- sendBackAnalyticsResultsOrError(req, res, error, results);
3933
- });
3934
- });
3935
- router.get("/:id/stats_votes", auth.can("edit group"), function (req, res) {
3936
- countModelRowsByTimePeriod(req, "stats_votes_" + req.params.id + "_group", models.AcActivity, {
3937
- type: {
3938
- $in: [
3939
- "activity.post.opposition.new",
3940
- "activity.post.endorsement.new",
3941
- "activity.point.helpful.new",
3942
- "activity.point.unhelpful.new",
3943
- ],
3944
- },
3945
- }, getGroupIncludes(req.params.id), (error, results) => {
3946
- sendBackAnalyticsResultsOrError(req, res, error, results);
3947
- });
3948
- });
3949
- router.get("/:id/get_translation_texts", auth.can("edit group"), function (req, res) {
3950
- getTranslatedTextsForGroup(req.query.targetLocale, req.params.id, (results, error) => {
3951
- if (error) {
3952
- log.error("Error in getting translated texts", { error });
3953
- res.sendStatus(500);
3954
- }
3955
- else {
3956
- res.send(results);
3957
- }
3958
- });
3959
- });
3960
- router.put("/:id/update_translation", auth.can("edit group"), function (req, res) {
3961
- updateTranslationForGroup(req.params.id, req.body, (results, error) => {
3962
- if (error) {
3963
- log.error("Error in updating translation", { error });
3964
- res.sendStatus(500);
3965
- }
3966
- else {
3967
- res.send(results);
3968
- }
3969
- });
3970
- });
3971
- router.put("/:id/update_structured_translations", auth.can("edit group"), function (req, res) {
3972
- let textType;
3973
- if (req.body.type == "registration") {
3974
- textType = "GroupRegQuestions";
3975
- }
3976
- else if (req.body.type.indexOf("PostAnswer") > -1) {
3977
- textType = "PostAnswer";
3978
- }
3979
- else {
3980
- textType = "GroupQuestions";
3981
- }
3982
- if (textType === "PostAnswer") {
3983
- let contentHash = req.body.type.split("-")[3];
3984
- let postId = req.body.type.split("-")[1];
3985
- updateAnswerTranslation(postId, textType, req.body.targetLocale, req.body.translations, contentHash, (results, error) => {
3986
- if (error) {
3987
- log.error("Error in updating survey translation", { error });
3988
- res.sendStatus(500);
3989
- }
3990
- else {
3991
- res.send(results);
3992
- }
3993
- });
3994
- }
3995
- else {
3996
- updateSurveyTranslation(req.params.id, textType, req.body.targetLocale, req.body.translations, req.body.questions, (results, error) => {
3997
- if (error) {
3998
- log.error("Error in updating survey translation", { error });
3999
- res.sendStatus(500);
4000
- }
4001
- else {
4002
- res.send(results);
4003
- }
4004
- });
4005
- }
4006
- });
4007
- var upload = multer({
4008
- storage: s3multer({
4009
- dirname: "attachments",
4010
- s3: s3,
4011
- bucket: process.env.S3_BUCKET,
4012
- secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
4013
- accessKeyId: process.env.AWS_ACCESS_KEY_ID,
4014
- endpoint: process.env.S3_ENDPOINT || null,
4015
- acl: "public-read",
4016
- contentType: s3multer.AUTO_CONTENT_TYPE,
4017
- region: process.env.S3_REGION || (process.env.S3_ENDPOINT ? null : "us-east-1"),
4018
- key: function (req, file, cb) {
4019
- cb(null, Date.now() + "_" + file.originalname);
4020
- },
4021
- }),
4022
- });
4023
- //TODO: Old remove only here for cached serviceworker clients
4024
- router.post("/:id/upload_document", auth.can("add to group"), upload.single("file"), function (req, res) {
4025
- res.send({ filename: req.file.originalname, url: req.file.location });
4026
- });
4027
- var uploadDox = multer({});
4028
- router.put("/:id/convert_docx_survey_to_json", uploadDox.single("file"), function (req, res) {
4029
- const formData = {
4030
- file: {
4031
- value: req.file.buffer,
4032
- options: {
4033
- filename: req.file.originalname,
4034
- },
4035
- },
4036
- };
4037
- convertDocxSurveyToJson(formData, (error, results) => {
4038
- if (error) {
4039
- log.error("Error in converting docx to joson", { error });
4040
- res.sendStatus(500);
4041
- }
4042
- else {
4043
- if (results.body) {
4044
- res.send({ jsonContent: JSON.parse(results.body) });
4045
- }
4046
- else {
4047
- res.sendStatus(500);
4048
- }
4049
- }
4050
- });
4051
- });
4052
- router.put("/:groupId/plausibleStatsProxy", auth.can("edit group marketing"), async (req, res) => {
4053
- try {
4054
- const plausibleData = await plausibleStatsProxy(req.body.plausibleUrl, {
4055
- groupId: req.params.groupId,
4056
- });
4057
- res.send(plausibleData);
4058
- }
4059
- catch (error) {
4060
- log.error("Could not get plausibleStatsProxy", {
4061
- err: error,
4062
- context: "getPlausibleSeries",
4063
- user: toJson(req.user.simple()),
4064
- });
4065
- res.sendStatus(500);
4066
- }
4067
- });
4068
- router.get("/:domainId/getTemplates", auth.can("view domain"), async (req, res) => {
4069
- try {
4070
- const userId = req.user.id;
4071
- const domainId = req.params.domainId;
4072
- const templateGroups = await models.Group.findAll({
4073
- where: {
4074
- [Op.and]: [
4075
- { "configuration.useAsTemplate": true },
4076
- {
4077
- [Op.or]: [
4078
- // public templates
4079
- { access: models.Group.ACCESS_PUBLIC },
4080
- // templates where user is an admin
4081
- literal(`"GroupAdmins"."id" IS NOT NULL`)
4082
- ]
4083
- }
4084
- ]
4085
- },
4086
- include: [
4087
- {
4088
- model: models.User,
4089
- as: "GroupAdmins",
4090
- attributes: [],
4091
- through: { attributes: [] },
4092
- where: { id: userId },
4093
- required: false,
4094
- },
4095
- {
4096
- model: models.Community,
4097
- as: "Community",
4098
- attributes: ["id", "name"],
4099
- required: true,
4100
- include: [
4101
- {
4102
- model: models.Domain,
4103
- attributes: ["id", "name"],
4104
- required: true,
4105
- where: { id: domainId }
4106
- },
4107
- ],
4108
- }
4109
- ],
4110
- attributes: ["id", "name"],
4111
- distinct: true,
4112
- order: [["name", "ASC"]]
4113
- });
4114
- res.send(templateGroups || []);
4115
- }
4116
- catch (error) {
4117
- log.error("Could not get template groups", {
4118
- err: error,
4119
- context: "getTemplates",
4120
- user: toJson(req.user.simple()),
4121
- });
4122
- res.sendStatus(500);
4123
- }
4124
- });
4125
- router.get("/:groupId/:type/getPlausibleSeries", auth.can("edit group marketing"), async (req, res) => {
4126
- // Example: "timeseries?site_id=your-priorities&period=7d";
4127
- try {
4128
- const questionMarkIndex = req.url.indexOf("?");
4129
- const queryString = req.url.substr(questionMarkIndex + 1);
4130
- const siteId = process.env.PLAUSIBLE_SITE_NAME;
4131
- const type = req.params.type.replace("realtime-visitors", "realtime/visitors");
4132
- const plausibleString = `${type}?${queryString}&site_id=${siteId}`;
4133
- const plausibleData = await getPlausibleStats(plausibleString);
4134
- log.info("GOT DATA");
4135
- log.info(plausibleData);
4136
- res.send(plausibleData);
4137
- }
4138
- catch (error) {
4139
- log.error("Could not get getPlausibleSeries", {
4140
- err: error,
4141
- context: "getPlausibleSeries",
4142
- user: toJson(req.user.simple()),
4143
- });
4144
- res.sendStatus(500);
4145
- }
4146
- });
4147
- router.get("/:groupId/get_campaigns", auth.can("edit group marketing"), async (req, res) => {
4148
- try {
4149
- const campaigns = await models.Campaign.findAll({
4150
- where: {
4151
- group_id: req.params.groupId,
4152
- },
4153
- order: [["created_at", "desc"]],
4154
- attributes: ["id", "configuration"],
4155
- });
4156
- res.send(campaigns);
4157
- }
4158
- catch (error) {
4159
- log.error("Could not get campaigns", {
4160
- err: error,
4161
- context: "get_campaigns",
4162
- user: toJson(req.user.simple()),
4163
- });
4164
- res.sendStatus(500);
4165
- }
4166
- });
4167
- router.post("/:groupId/create_campaign", auth.can("edit group marketing"), async (req, res) => {
4168
- try {
4169
- const campaign = models.Campaign.build({
4170
- group_id: req.params.groupId,
4171
- configuration: req.body.configuration,
4172
- user_id: req.user.id,
4173
- });
4174
- await campaign.save();
4175
- //TODO: Toxicity check
4176
- res.send(campaign);
4177
- }
4178
- catch (error) {
4179
- log.error("Could not create_campaign campaigns", {
4180
- err: error,
4181
- context: "create_campaign",
4182
- user: toJson(req.user.simple()),
4183
- });
4184
- res.sendStatus(500);
4185
- }
4186
- });
4187
- router.put("/:groupId/:campaignId/update_campaign", auth.can("edit group marketing"), async (req, res) => {
4188
- try {
4189
- const campaign = await models.Campaign.findOne({
4190
- where: {
4191
- id: req.params.campaignId,
4192
- group_id: req.params.groupId,
4193
- },
4194
- attributes: ["id", "configuration"],
4195
- });
4196
- campaign.configuration = req.body.configuration;
4197
- await campaign.save();
4198
- //TODO: Toxicity check
4199
- res.send(campaign);
4200
- }
4201
- catch (error) {
4202
- log.error("Could not create_campaign campaigns", {
4203
- err: error,
4204
- context: "create_campaign",
4205
- user: toJson(req.user.simple()),
4206
- });
4207
- res.sendStatus(500);
4208
- }
4209
- });
4210
- router.delete("/:groupId/:campaignId/delete_campaign", auth.can("edit group marketing"), async (req, res) => {
4211
- try {
4212
- const campaign = await models.Campaign.findOne({
4213
- where: {
4214
- id: req.params.campaignId,
4215
- group_id: req.params.groupId,
4216
- },
4217
- attributes: ["id"],
4218
- });
4219
- campaign.deleted = true;
4220
- await campaign.save();
4221
- res.sendStatus(200);
4222
- }
4223
- catch (error) {
4224
- log.error("Could not delete_campaign campaigns", {
4225
- err: error,
4226
- context: "delete_campaign",
4227
- user: toJson(req.user.simple()),
4228
- });
4229
- res.sendStatus(500);
4230
- }
4231
- });
4232
- router.get("/:groupId/get_posts_with_public_private", auth.can("view group"), async (req, res) => {
4233
- try {
4234
- const posts = await models.Post.findAll({
4235
- where: {
4236
- group_id: req.params.groupId,
4237
- [Sequelize.Op.and]: [
4238
- Sequelize.literal(`"data"->'publicPrivateData' IS NOT NULL`),
4239
- ],
4240
- },
4241
- order: [["created_at", "desc"]],
4242
- attributes: [
4243
- "id",
4244
- [
4245
- models.sequelize.literal("\"data\"->'publicPrivateData'"),
4246
- "publicPrivateData",
4247
- ],
4248
- ],
4249
- });
4250
- res.send(posts);
4251
- }
4252
- catch (error) {
4253
- log.error("Could not get get_posts_with_public_private", {
4254
- err: error,
4255
- context: "get_campaigns",
4256
- user: toJson(req.user.simple()),
4257
- });
4258
- res.sendStatus(500);
4259
- }
4260
- });
4261
- router.get("/:groupId/:pointId/get_parent_point", auth.can("view group"), async (req, res) => {
4262
- try {
4263
- const point = await models.Point.findOne({
4264
- where: {
4265
- group_id: req.params.groupId,
4266
- id: req.params.pointId,
4267
- },
4268
- order: [
4269
- [models.PointRevision, "created_at", "asc"],
4270
- [
4271
- models.User,
4272
- { model: models.Image, as: "UserProfileImages" },
4273
- "created_at",
4274
- "asc",
4275
- ],
4276
- ],
4277
- attributes: ["id", "content"],
4278
- include: [
4279
- {
4280
- model: models.PointRevision,
4281
- required: false,
4282
- },
4283
- {
4284
- model: models.User,
4285
- required: true,
4286
- attributes: models.User.defaultAttributesWithSocialMediaPublic,
4287
- include: [
4288
- {
4289
- model: models.Image,
4290
- as: "UserProfileImages",
4291
- attributes: ["id", "formats", "updated_at"],
4292
- required: false,
4293
- },
4294
- ],
4295
- },
4296
- ],
4297
- });
4298
- res.send(point);
4299
- }
4300
- catch (error) {
4301
- log.error("Could not get get_parent_point", {
4302
- err: error,
4303
- context: "get_campaigns",
4304
- user: toJson(req.user.simple()),
4305
- });
4306
- res.sendStatus(500);
4307
- }
4308
- });
4309
- module.exports = router;