@oneuptime/common 12.0.13 → 12.0.14

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 (376) hide show
  1. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
  2. package/Models/DatabaseModels/UserCall.ts +94 -3
  3. package/Models/DatabaseModels/UserEmail.ts +94 -3
  4. package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
  5. package/Models/DatabaseModels/UserPush.ts +37 -0
  6. package/Models/DatabaseModels/UserSMS.ts +94 -3
  7. package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
  8. package/Server/API/BaseAPI.ts +79 -14
  9. package/Server/API/UserCallAPI.ts +53 -45
  10. package/Server/API/UserEmailAPI.ts +53 -44
  11. package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
  12. package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
  13. package/Server/API/UserPushAPI.ts +126 -2
  14. package/Server/API/UserSmsAPI.ts +53 -44
  15. package/Server/API/UserWhatsAppAPI.ts +53 -50
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  20. package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
  21. package/Server/Services/AnalyticsDatabaseService.ts +169 -0
  22. package/Server/Services/DatabaseService.ts +101 -0
  23. package/Server/Services/LogAggregationService.ts +5 -0
  24. package/Server/Services/PushNotificationService.ts +127 -12
  25. package/Server/Services/TeamMemberService.ts +53 -13
  26. package/Server/Services/UserCallService.ts +55 -24
  27. package/Server/Services/UserEmailService.ts +83 -17
  28. package/Server/Services/UserIncomingCallNumberService.ts +49 -85
  29. package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
  30. package/Server/Services/UserNotificationRuleService.ts +26 -0
  31. package/Server/Services/UserPushService.ts +89 -0
  32. package/Server/Services/UserSmsService.ts +50 -17
  33. package/Server/Services/UserWhatsAppService.ts +48 -15
  34. package/Server/Types/Database/QueryHelper.ts +30 -0
  35. package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
  36. package/Server/Utils/ChannelVerification.ts +510 -0
  37. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
  38. package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
  39. package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
  40. package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
  41. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
  42. package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
  43. package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
  44. package/Server/Utils/TotpAuth.ts +137 -9
  45. package/Server/Utils/UserRegistrationToken.ts +182 -0
  46. package/Server/Utils/VerificationCode.ts +134 -0
  47. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
  48. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
  49. package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
  50. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
  51. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
  52. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +28 -0
  53. package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
  54. package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
  55. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
  56. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
  57. package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
  58. package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
  59. package/Tests/Server/API/UserSmsApi.test.ts +107 -14
  60. package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
  61. package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +315 -0
  62. package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
  63. package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
  64. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
  65. package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
  66. package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
  67. package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
  68. package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
  69. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
  70. package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
  71. package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
  72. package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
  73. package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
  74. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
  75. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
  76. package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
  77. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
  78. package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
  79. package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
  80. package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
  81. package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
  82. package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
  83. package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
  84. package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
  85. package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
  86. package/Tests/Server/Utils/Browser.test.ts +162 -0
  87. package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
  88. package/Tests/Server/Utils/Express.test.ts +371 -0
  89. package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
  90. package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
  91. package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
  92. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
  93. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
  94. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
  95. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
  96. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
  97. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
  98. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
  99. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
  100. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
  101. package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
  102. package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
  103. package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
  104. package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
  105. package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
  106. package/Tests/Types/Call/CallRequest.test.ts +189 -0
  107. package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
  108. package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
  109. package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
  110. package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
  111. package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
  112. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
  113. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
  114. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
  115. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
  116. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
  117. package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
  118. package/Tests/Types/TextRandomGeneration.test.ts +211 -0
  119. package/Tests/UI/Components/Button.test.tsx +175 -1
  120. package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
  121. package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
  122. package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
  123. package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
  124. package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
  125. package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
  126. package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
  127. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
  128. package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
  129. package/Tests/UI/Components/List.test.tsx +9 -2
  130. package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
  131. package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
  132. package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
  133. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
  134. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
  135. package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
  136. package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
  137. package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
  138. package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
  139. package/Tests/UI/Components/Skeleton.test.tsx +71 -0
  140. package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
  141. package/Tests/UI/Components/Tabs.test.tsx +24 -0
  142. package/Tests/UI/Components/Toast.test.tsx +130 -7
  143. package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
  144. package/Tests/UI/Utils/Dropdown.test.ts +423 -0
  145. package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
  146. package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
  147. package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
  148. package/Tests/Utils/API.test.ts +16 -2
  149. package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
  150. package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
  151. package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
  152. package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
  153. package/Types/Email/EmailTemplateType.ts +1 -0
  154. package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
  155. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
  156. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
  157. package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
  158. package/Types/Permission.ts +35 -0
  159. package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
  160. package/Types/PushNotification/PushNotificationMessage.ts +15 -0
  161. package/Types/PushNotification/PushNotificationRequest.ts +8 -16
  162. package/Types/Service/ServiceLanguage.ts +144 -0
  163. package/Types/Text.ts +111 -19
  164. package/UI/Components/Button/Button.tsx +27 -14
  165. package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
  166. package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
  167. package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
  168. package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
  169. package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
  170. package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
  171. package/UI/Components/CommandPalette/Types.ts +49 -0
  172. package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
  173. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  174. package/UI/Components/Feed/FeedItem.tsx +1 -1
  175. package/UI/Components/List/List.tsx +37 -5
  176. package/UI/Components/List/ListSkeleton.tsx +54 -0
  177. package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
  178. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
  179. package/UI/Components/Modal/Modal.tsx +2 -2
  180. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  181. package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
  182. package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
  183. package/UI/Components/Navbar/NavBar.tsx +14 -1
  184. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
  185. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
  186. package/UI/Components/SideOver/SideOver.tsx +37 -2
  187. package/UI/Components/Skeleton/Skeleton.tsx +53 -0
  188. package/UI/Components/Table/Table.tsx +74 -44
  189. package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
  190. package/UI/Components/Tabs/Tab.tsx +1 -1
  191. package/UI/Components/Toast/Toast.tsx +118 -53
  192. package/UI/Components/Toast/ToastInit.tsx +82 -32
  193. package/UI/Styles/Theme.css +40 -0
  194. package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
  195. package/UI/Utils/ModelListCache.ts +188 -0
  196. package/UI/Utils/Project.ts +29 -0
  197. package/Utils/API.ts +6 -1
  198. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
  199. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  200. package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
  201. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  202. package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
  203. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  204. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
  205. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
  206. package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
  207. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  208. package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
  209. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
  211. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  212. package/build/dist/Server/API/BaseAPI.js +69 -13
  213. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  214. package/build/dist/Server/API/UserCallAPI.js +42 -38
  215. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  216. package/build/dist/Server/API/UserEmailAPI.js +42 -38
  217. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  218. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
  219. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  220. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
  221. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
  222. package/build/dist/Server/API/UserPushAPI.js +95 -2
  223. package/build/dist/Server/API/UserPushAPI.js.map +1 -1
  224. package/build/dist/Server/API/UserSmsAPI.js +42 -38
  225. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  226. package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
  227. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  228. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
  233. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
  234. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  236. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
  237. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
  238. package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
  239. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  240. package/build/dist/Server/Services/DatabaseService.js +74 -0
  241. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  242. package/build/dist/Server/Services/LogAggregationService.js +5 -0
  243. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  244. package/build/dist/Server/Services/PushNotificationService.js +69 -30
  245. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  246. package/build/dist/Server/Services/TeamMemberService.js +43 -7
  247. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  248. package/build/dist/Server/Services/UserCallService.js +54 -22
  249. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  250. package/build/dist/Server/Services/UserEmailService.js +78 -17
  251. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  252. package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
  253. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
  254. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
  255. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
  256. package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
  257. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  258. package/build/dist/Server/Services/UserPushService.js +77 -0
  259. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  260. package/build/dist/Server/Services/UserSmsService.js +50 -17
  261. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  262. package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
  263. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  264. package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
  265. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  266. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
  267. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
  268. package/build/dist/Server/Utils/ChannelVerification.js +348 -0
  269. package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
  270. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
  271. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  272. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
  273. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  274. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
  275. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  276. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
  277. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
  278. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
  279. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
  280. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
  281. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
  282. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  283. package/build/dist/Server/Utils/TotpAuth.js +127 -8
  284. package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
  285. package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
  286. package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
  287. package/build/dist/Server/Utils/VerificationCode.js +120 -0
  288. package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
  289. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  290. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  291. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
  292. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  293. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
  294. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  295. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
  296. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  297. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
  298. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
  299. package/build/dist/Types/Permission.js +33 -0
  300. package/build/dist/Types/Permission.js.map +1 -1
  301. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
  302. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
  303. package/build/dist/Types/Service/ServiceLanguage.js +96 -0
  304. package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
  305. package/build/dist/Types/Text.js +82 -17
  306. package/build/dist/Types/Text.js.map +1 -1
  307. package/build/dist/UI/Components/Button/Button.js +22 -14
  308. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  309. package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
  310. package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
  311. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
  312. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
  313. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
  314. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
  315. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
  316. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
  317. package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
  318. package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
  319. package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
  320. package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
  321. package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
  322. package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
  323. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
  324. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
  325. package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
  326. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  327. package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
  328. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  329. package/build/dist/UI/Components/List/List.js +19 -5
  330. package/build/dist/UI/Components/List/List.js.map +1 -1
  331. package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
  332. package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
  333. package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
  334. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
  335. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  336. package/build/dist/UI/Components/Modal/Modal.js +2 -2
  337. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  338. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  339. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
  340. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  341. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
  342. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  343. package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
  344. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  345. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
  346. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  347. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
  348. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  349. package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
  350. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  351. package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
  352. package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
  353. package/build/dist/UI/Components/Table/Table.js +35 -24
  354. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  355. package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
  356. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
  357. package/build/dist/UI/Components/Tabs/Tab.js +1 -1
  358. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  359. package/build/dist/UI/Components/Toast/Toast.js +77 -23
  360. package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
  361. package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
  362. package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
  363. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
  364. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  365. package/build/dist/UI/Utils/ModelListCache.js +126 -0
  366. package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
  367. package/build/dist/UI/Utils/Project.js +24 -1
  368. package/build/dist/UI/Utils/Project.js.map +1 -1
  369. package/build/dist/Utils/API.js +6 -1
  370. package/build/dist/Utils/API.js.map +1 -1
  371. package/jest.config.json +1 -1
  372. package/package.json +2 -3
  373. package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
  374. package/Tests/__mocks__/otpauth.js +0 -30
  375. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
  376. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
@@ -1,18 +1,36 @@
1
1
  import UserMiddleware from "../Middleware/UserAuthorization";
2
+ import VerificationCodeRateLimit, { VerificationCodeRateLimitBucket, } from "../Middleware/VerificationCodeRateLimit";
2
3
  import UserEmailService from "../Services/UserEmailService";
3
- import UserNotificationRuleService from "../Services/UserNotificationRuleService";
4
+ import ChannelVerification, { ChannelVerificationOutcome, } from "../Utils/ChannelVerification";
4
5
  import Response from "../Utils/Response";
5
- import logger, { getLogAttributesFromRequest } from "../Utils/Logger";
6
6
  import BaseAPI from "./BaseAPI";
7
7
  import BadDataException from "../../Types/Exception/BadDataException";
8
8
  import ObjectID from "../../Types/ObjectID";
9
9
  import UserEmail from "../../Models/DatabaseModels/UserEmail";
10
+ import UserNotificationRuleService from "../Services/UserNotificationRuleService";
11
+ import logger, { getLogAttributesFromRequest } from "../Utils/Logger";
12
+ /*
13
+ * The verify and resend routes for this notification channel.
14
+ *
15
+ * Neither the checking of a submitted code nor the issuing of a new one lives
16
+ * here, on purpose. The state machine is shared by all five channels
17
+ * (Common/Server/Utils/ChannelVerification.ts) so that a control added for one
18
+ * of them cannot quietly go missing on another — which is exactly what went
19
+ * wrong before: five hand-written copies of "compare the column, set
20
+ * isVerified", none of which expired the code, counted attempts, or refused a
21
+ * caller running the comparison a million times against somebody else's phone
22
+ * number.
23
+ *
24
+ * What is left here is the HTTP shape: reject malformed bodies, run the rate
25
+ * limiter before anything costs a database read, and turn the outcome into a
26
+ * response.
27
+ */
10
28
  export default class UserEmailAPI extends BaseAPI {
11
29
  constructor() {
12
30
  var _a, _b;
13
31
  super(UserEmail, UserEmailService);
14
- this.router.post(`${(_a = new this.entityType().getCrudApiPath()) === null || _a === void 0 ? void 0 : _a.toString()}/verify`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
15
- var _a, _b, _c;
32
+ this.router.post(`${(_a = new this.entityType().getCrudApiPath()) === null || _a === void 0 ? void 0 : _a.toString()}/verify`, UserMiddleware.getUserMiddleware, VerificationCodeRateLimit.getMiddleware(VerificationCodeRateLimitBucket.Verify), async (req, res, next) => {
33
+ var _a;
16
34
  try {
17
35
  req = req;
18
36
  if (!req.body.itemId) {
@@ -21,45 +39,26 @@ export default class UserEmailAPI extends BaseAPI {
21
39
  if (!req.body.code) {
22
40
  return Response.sendErrorResponse(req, res, new BadDataException("Invalid code"));
23
41
  }
24
- // Check if the code matches and verify the email.
25
- const item = await this.service.findOneById({
26
- id: req.body["itemId"],
27
- props: {
28
- isRoot: true,
29
- },
30
- select: {
31
- userId: true,
32
- projectId: true,
33
- verificationCode: true,
34
- },
35
- });
36
- if (!item) {
37
- return Response.sendErrorResponse(req, res, new BadDataException("Item not found"));
38
- }
39
- //check user id
40
- if (((_a = item.userId) === null || _a === void 0 ? void 0 : _a.toString()) !==
41
- ((_c = (_b = req === null || req === void 0 ? void 0 : req.userAuthorization) === null || _b === void 0 ? void 0 : _b.userId) === null || _c === void 0 ? void 0 : _c.toString())) {
42
+ const userId = (_a = req === null || req === void 0 ? void 0 : req.userAuthorization) === null || _a === void 0 ? void 0 : _a.userId;
43
+ if (!userId) {
42
44
  return Response.sendErrorResponse(req, res, new BadDataException("Invalid user ID"));
43
45
  }
44
- if (item.verificationCode !== req.body["code"]) {
45
- return Response.sendErrorResponse(req, res, new BadDataException("Invalid code"));
46
- }
47
- await this.service.updateOneById({
48
- id: item.id,
49
- props: {
50
- isRoot: true,
51
- },
52
- data: {
53
- isVerified: true,
54
- },
46
+ const result = await ChannelVerification.verifyCode({
47
+ service: this.service,
48
+ itemId: new ObjectID(req.body["itemId"].toString()),
49
+ userId: userId,
50
+ code: req.body["code"].toString(),
55
51
  });
56
- // Create default notification rules for this verified email
52
+ if (result.outcome !== ChannelVerificationOutcome.Verified) {
53
+ return Response.sendErrorResponse(req, res, ChannelVerification.getFailureException(result.outcome));
54
+ }
55
+ /* Create default notification rules for this verified email */
57
56
  try {
58
57
  await UserNotificationRuleService.addDefaultNotificationRulesForVerifiedMethod({
59
- projectId: new ObjectID(item.projectId.toString()),
60
- userId: new ObjectID(item.userId.toString()),
58
+ projectId: new ObjectID(result.projectId.toString()),
59
+ userId: new ObjectID(result.userId.toString()),
61
60
  notificationMethod: {
62
- userEmailId: item.id,
61
+ userEmailId: result.itemId,
63
62
  },
64
63
  });
65
64
  }
@@ -73,7 +72,7 @@ export default class UserEmailAPI extends BaseAPI {
73
72
  }
74
73
  });
75
74
  this.router.post(`${(_b = new this.entityType()
76
- .getCrudApiPath()) === null || _b === void 0 ? void 0 : _b.toString()}/resend-verification-code`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
75
+ .getCrudApiPath()) === null || _b === void 0 ? void 0 : _b.toString()}/resend-verification-code`, UserMiddleware.getUserMiddleware, VerificationCodeRateLimit.getMiddleware(VerificationCodeRateLimitBucket.Resend), async (req, res, next) => {
77
76
  var _a, _b, _c;
78
77
  try {
79
78
  req = req;
@@ -92,6 +91,11 @@ export default class UserEmailAPI extends BaseAPI {
92
91
  if (!item) {
93
92
  return Response.sendErrorResponse(req, res, new BadDataException("Item not found"));
94
93
  }
94
+ /*
95
+ * A caller may only ask for a code to be sent to a row they own.
96
+ * Without this the resend route is a way to make somebody else's
97
+ * device ring on demand.
98
+ */
95
99
  if (((_a = item.userId) === null || _a === void 0 ? void 0 : _a.toString()) !==
96
100
  ((_c = (_b = req === null || req === void 0 ? void 0 : req.userAuthorization) === null || _b === void 0 ? void 0 : _b.userId) === null || _c === void 0 ? void 0 : _c.toString())) {
97
101
  return Response.sendErrorResponse(req, res, new BadDataException("Invalid user ID"));
@@ -1 +1 @@
1
- {"version":3,"file":"UserEmailAPI.js","sourceRoot":"","sources":["../../../../Server/API/UserEmailAPI.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UserEmailAPI.js","sourceRoot":"","sources":["../../../../Server/API/UserEmailAPI.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,33 @@
1
1
  import UserMiddleware from "../Middleware/UserAuthorization";
2
+ import VerificationCodeRateLimit, { VerificationCodeRateLimitBucket, } from "../Middleware/VerificationCodeRateLimit";
2
3
  import UserIncomingCallNumberService from "../Services/UserIncomingCallNumberService";
4
+ import ChannelVerification, { ChannelVerificationOutcome, } from "../Utils/ChannelVerification";
3
5
  import Response from "../Utils/Response";
4
6
  import BaseAPI from "./BaseAPI";
5
7
  import BadDataException from "../../Types/Exception/BadDataException";
8
+ import ObjectID from "../../Types/ObjectID";
6
9
  import UserIncomingCallNumber from "../../Models/DatabaseModels/UserIncomingCallNumber";
10
+ /*
11
+ * The verify and resend routes for this notification channel.
12
+ *
13
+ * Neither the checking of a submitted code nor the issuing of a new one lives
14
+ * here, on purpose. The state machine is shared by all five channels
15
+ * (Common/Server/Utils/ChannelVerification.ts) so that a control added for one
16
+ * of them cannot quietly go missing on another — which is exactly what went
17
+ * wrong before: five hand-written copies of "compare the column, set
18
+ * isVerified", none of which expired the code, counted attempts, or refused a
19
+ * caller running the comparison a million times against somebody else's phone
20
+ * number.
21
+ *
22
+ * What is left here is the HTTP shape: reject malformed bodies, run the rate
23
+ * limiter before anything costs a database read, and turn the outcome into a
24
+ * response.
25
+ */
7
26
  export default class UserIncomingCallNumberAPI extends BaseAPI {
8
27
  constructor() {
9
28
  super(UserIncomingCallNumber, UserIncomingCallNumberService);
10
- this.router.post(`/user-incoming-call-number/verify`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
11
- var _a, _b, _c;
29
+ this.router.post(`/user-incoming-call-number/verify`, UserMiddleware.getUserMiddleware, VerificationCodeRateLimit.getMiddleware(VerificationCodeRateLimitBucket.Verify), async (req, res, next) => {
30
+ var _a;
12
31
  try {
13
32
  req = req;
14
33
  if (!req.body.itemId) {
@@ -17,44 +36,26 @@ export default class UserIncomingCallNumberAPI extends BaseAPI {
17
36
  if (!req.body.code) {
18
37
  return Response.sendErrorResponse(req, res, new BadDataException("Invalid code"));
19
38
  }
20
- // Check if the code matches and verify the phone number
21
- const item = await this.service.findOneById({
22
- id: req.body["itemId"],
23
- props: {
24
- isRoot: true,
25
- },
26
- select: {
27
- userId: true,
28
- verificationCode: true,
29
- },
30
- });
31
- if (!item) {
32
- return Response.sendErrorResponse(req, res, new BadDataException("Item not found"));
33
- }
34
- // Check user ID
35
- if (((_a = item.userId) === null || _a === void 0 ? void 0 : _a.toString()) !==
36
- ((_c = (_b = req === null || req === void 0 ? void 0 : req.userAuthorization) === null || _b === void 0 ? void 0 : _b.userId) === null || _c === void 0 ? void 0 : _c.toString())) {
39
+ const userId = (_a = req === null || req === void 0 ? void 0 : req.userAuthorization) === null || _a === void 0 ? void 0 : _a.userId;
40
+ if (!userId) {
37
41
  return Response.sendErrorResponse(req, res, new BadDataException("Invalid user ID"));
38
42
  }
39
- if (item.verificationCode !== req.body["code"]) {
40
- return Response.sendErrorResponse(req, res, new BadDataException("Invalid code"));
41
- }
42
- await this.service.updateOneById({
43
- id: item.id,
44
- props: {
45
- isRoot: true,
46
- },
47
- data: {
48
- isVerified: true,
49
- },
43
+ const result = await ChannelVerification.verifyCode({
44
+ service: this.service,
45
+ itemId: new ObjectID(req.body["itemId"].toString()),
46
+ userId: userId,
47
+ code: req.body["code"].toString(),
50
48
  });
49
+ if (result.outcome !== ChannelVerificationOutcome.Verified) {
50
+ return Response.sendErrorResponse(req, res, ChannelVerification.getFailureException(result.outcome));
51
+ }
51
52
  return Response.sendEmptySuccessResponse(req, res);
52
53
  }
53
54
  catch (err) {
54
55
  return next(err);
55
56
  }
56
57
  });
57
- this.router.post(`/user-incoming-call-number/resend-verification-code`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
58
+ this.router.post(`/user-incoming-call-number/resend-verification-code`, UserMiddleware.getUserMiddleware, VerificationCodeRateLimit.getMiddleware(VerificationCodeRateLimitBucket.Resend), async (req, res, next) => {
58
59
  var _a, _b, _c;
59
60
  try {
60
61
  req = req;
@@ -73,7 +74,11 @@ export default class UserIncomingCallNumberAPI extends BaseAPI {
73
74
  if (!item) {
74
75
  return Response.sendErrorResponse(req, res, new BadDataException("Item not found"));
75
76
  }
76
- // Check user ID
77
+ /*
78
+ * A caller may only ask for a code to be sent to a row they own.
79
+ * Without this the resend route is a way to make somebody else's
80
+ * device ring on demand.
81
+ */
77
82
  if (((_a = item.userId) === null || _a === void 0 ? void 0 : _a.toString()) !==
78
83
  ((_c = (_b = req === null || req === void 0 ? void 0 : req.userAuthorization) === null || _b === void 0 ? void 0 : _b.userId) === null || _c === void 0 ? void 0 : _c.toString())) {
79
84
  return Response.sendErrorResponse(req, res, new BadDataException("Invalid user ID"));
@@ -1 +1 @@
1
- {"version":3,"file":"UserIncomingCallNumberAPI.js","sourceRoot":"","sources":["../../../../Server/API/UserIncomingCallNumberAPI.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UserIncomingCallNumberAPI.js","sourceRoot":"","sources":["../../../../Server/API/UserIncomingCallNumberAPI.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,341 @@
1
+ import UserMiddleware from "../Middleware/UserAuthorization";
2
+ import UserNotificationMethodAdminService from "../Services/UserNotificationMethodAdminService";
3
+ import TeamMemberService from "../Services/TeamMemberService";
4
+ import Express from "../Utils/Express";
5
+ import Response from "../Utils/Response";
6
+ import CommonAPI from "./CommonAPI";
7
+ import DatabaseCommonInteractionPropsUtil, { PermissionType, } from "../../Types/BaseDatabase/DatabaseCommonInteractionPropsUtil";
8
+ import BadDataException from "../../Types/Exception/BadDataException";
9
+ import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
10
+ import ObjectID from "../../Types/ObjectID";
11
+ import Permission from "../../Types/Permission";
12
+ /*
13
+ * Managing another project member's notification methods over HTTP.
14
+ *
15
+ * Everything this router does is done by UserNotificationMethodAdminService,
16
+ * which holds the whole of the reasoning about masking, verification and the
17
+ * owner's mail. This file is transport and AUTHORISATION, and the authorisation
18
+ * is the part worth reading, because the usual reasoning does not apply here.
19
+ *
20
+ * The seven notification method models are scoped to the person who owns the
21
+ * device, and they stay that way — see the essay at the top of UserEmail.ts.
22
+ * The service therefore does its reads and writes with `isRoot: true`, which
23
+ * means the model's own TableAccessControl never runs on this path AND THESE
24
+ * HANDLERS ARE THE ONLY GATE UNDERNEATH. UserMiddleware.getUserMiddleware is
25
+ * not that gate: it admits anonymous callers as UserType.Public and calls
26
+ * next(), and the tenant id it attaches comes straight off the caller-supplied
27
+ * `tenantid` header before any authorisation runs.
28
+ *
29
+ * So every route below asserts, itself, in this order:
30
+ *
31
+ * 1. the caller is a signed-in member of the project they named
32
+ * (CommonAPI.assertAuthenticatedProjectMember, which checks the caller
33
+ * against that same header);
34
+ * 2. the caller holds a permission that lets them act on other people's
35
+ * accounts in it (assertCanManageUserNotificationMethods below), EXCEPT on
36
+ * the read, which additionally lets a person read their own; and
37
+ * 3. the user named in the path is a member of that same project — enforced
38
+ * again inside the service, on purpose, so the service is safe for any
39
+ * caller and not only for this router.
40
+ *
41
+ * WHY THE READ IS SEPARATELY GATED FROM THE WRITES. Reading the masked list is
42
+ * a disclosure ("this person has an unverified SMS"), and the readiness surface
43
+ * already discloses exactly that to every project member. Writing is an ACTION
44
+ * on somebody else's account. Those are different questions and the router does
45
+ * not answer them with one permission.
46
+ */
47
+ const router = Express.getRouter();
48
+ /*
49
+ * Who may LOOK at another member's notification methods.
50
+ *
51
+ * The same triple the admin rules page uses, and for the same reason: existing
52
+ * project teams are seeded with ROLES, never with individual granular
53
+ * permissions, so a permission introduced in this release is held by nobody at
54
+ * all until an administrator explicitly grants it. A gate naming only the
55
+ * granular permission would ship a feature that is dead on arrival for every
56
+ * project that already exists — the owner of a project would open the page and
57
+ * be told they may not look at it.
58
+ */
59
+ const READ_PERMISSIONS = [
60
+ Permission.ProjectOwner,
61
+ Permission.ProjectAdmin,
62
+ Permission.ReadProjectUserNotificationRule,
63
+ ];
64
+ /*
65
+ * Who may ADD or REMOVE one.
66
+ *
67
+ * Deliberately NOT EditProjectUserNotificationRule. Repairing somebody's rules
68
+ * and putting a new address on their account are different powers with
69
+ * different blast radii: the first re-points pages between devices that person
70
+ * has already proved they hold, the second introduces a device nobody has
71
+ * proved anything about. An installation that wants to hand out the first
72
+ * without the second must be able to, so this is its own permission.
73
+ */
74
+ const MANAGE_PERMISSIONS = [
75
+ Permission.ProjectOwner,
76
+ Permission.ProjectAdmin,
77
+ Permission.ManageProjectUserNotificationMethod,
78
+ ];
79
+ /*
80
+ * The permission check, read the way the rest of the API reads permissions.
81
+ *
82
+ * getUserPermissions(Allow) rather than indexing userTenantAccessPermission
83
+ * directly, and that is not a stylistic preference. That dictionary's entries
84
+ * hold GRANTS AND DENIALS in one array, discriminated only by
85
+ * `isBlockPermission`, so mapping it raw would count a team's explicit BLOCK of
86
+ * ProjectAdmin as a grant of it — the admin action that restricts a team would
87
+ * be the thing that handed it this endpoint.
88
+ *
89
+ * Every refusal in this file reuses one sentence, so an under-privileged member
90
+ * cannot tell "you may not do this" apart from "you are not in this project"
91
+ * and use the difference to probe.
92
+ */
93
+ function assertHasAnyPermission(databaseProps, allowed) {
94
+ if (databaseProps.isMasterAdmin) {
95
+ return;
96
+ }
97
+ const permissions = DatabaseCommonInteractionPropsUtil.getUserPermissions(databaseProps, PermissionType.Allow).map((userPermission) => {
98
+ return userPermission.permission;
99
+ });
100
+ const isAllowed = permissions.some((permission) => {
101
+ return allowed.includes(permission);
102
+ });
103
+ if (!isAllowed) {
104
+ throw new NotAuthorizedException("You are not authorized to access this project's data.");
105
+ }
106
+ }
107
+ /*
108
+ * Project membership for the user NAMED IN THE PATH, not the caller.
109
+ *
110
+ * Without it these routes are a cross-project probe: the service's reads are
111
+ * projectId-scoped and would come back empty for a stranger, but a write path
112
+ * that skipped this would let somebody holding ProjectAdmin on one throwaway
113
+ * project act on a user id belonging to any other.
114
+ *
115
+ * The rejection reuses the router's single refusal sentence so a caller cannot
116
+ * tell "this user exists but is in another project" apart from "this user does
117
+ * not exist", and therefore cannot enumerate users through it. The service
118
+ * repeats the check with its own wording once the caller is past this point.
119
+ */
120
+ async function assertUserBelongsToProject(userId, projectId) {
121
+ const memberships = await TeamMemberService.findBy({
122
+ query: {
123
+ userId: userId,
124
+ projectId: projectId,
125
+ },
126
+ select: {
127
+ _id: true,
128
+ },
129
+ limit: 1,
130
+ skip: 0,
131
+ props: {
132
+ isRoot: true,
133
+ },
134
+ });
135
+ if (memberships.length === 0) {
136
+ throw new NotAuthorizedException("You are not authorized to access this project's data.");
137
+ }
138
+ }
139
+ /*
140
+ * ObjectID's constructor accepts any string, so an unvalidated path segment
141
+ * would travel all the way to a query that matches nothing and read as "this
142
+ * user has no notification methods" rather than as "you sent nonsense".
143
+ */
144
+ function readObjectIdParam(req, name) {
145
+ const raw = req.params[name] || "";
146
+ ObjectID.validateUUID(raw);
147
+ return new ObjectID(raw);
148
+ }
149
+ function readStringFromBody(req, name) {
150
+ const body = (req.body || {});
151
+ const raw = body[name];
152
+ if (typeof raw !== "string" || !raw.trim()) {
153
+ throw new BadDataException(`${name} is required.`);
154
+ }
155
+ return raw.trim();
156
+ }
157
+ /*
158
+ * ObjectID.toJSON() serialises to `{ _type: "ObjectID", value: "..." }`, which
159
+ * is right for model payloads the client parses back through JSONFunctions but
160
+ * wrong for a hand-rolled response body. Ids are flattened to plain strings, the
161
+ * same way OnCallReadinessAPI does it, so the browser can read `methodId`
162
+ * without knowing about ObjectID at all.
163
+ *
164
+ * `maskedIdentifier` is copied and nothing else is: there is no raw field on
165
+ * the service's view type to leak, which is deliberate — a future change would
166
+ * have to widen that contract in the open rather than slip a phone number
167
+ * through a boolean flag here.
168
+ */
169
+ function serializeMethod(method) {
170
+ return {
171
+ methodId: method.methodId.toString(),
172
+ methodType: method.methodType,
173
+ maskedIdentifier: method.maskedIdentifier,
174
+ isVerified: method.isVerified,
175
+ isAdminAddable: method.isAdminAddable,
176
+ createdAt: method.createdAt ? method.createdAt.toISOString() : undefined,
177
+ };
178
+ }
179
+ /*
180
+ * Every notification method this user has, masked.
181
+ *
182
+ * A member reading their OWN row is allowed through without the admin
183
+ * permission. The page behind this is reachable from the project's user list,
184
+ * and a person looking at themselves there is reading rows the self-serve
185
+ * settings pages already show them in full.
186
+ */
187
+ router.get("/user-notification-method-admin/user/:userId", UserMiddleware.getUserMiddleware, async (req, res, next) => {
188
+ try {
189
+ const databaseProps = await CommonAPI.getDatabaseCommonInteractionProps(req);
190
+ const projectId = CommonAPI.assertAuthenticatedProjectMember(databaseProps);
191
+ const userId = readObjectIdParam(req, "userId");
192
+ const isSelf = Boolean(databaseProps.userId) &&
193
+ databaseProps.userId.toString() === userId.toString();
194
+ if (!isSelf) {
195
+ assertHasAnyPermission(databaseProps, READ_PERMISSIONS);
196
+ }
197
+ await assertUserBelongsToProject(userId, projectId);
198
+ const methods = await UserNotificationMethodAdminService.listMethodsForUser({
199
+ projectId: projectId,
200
+ userId: userId,
201
+ });
202
+ return Response.sendJsonObjectResponse(req, res, {
203
+ methods: methods.map(serializeMethod),
204
+ });
205
+ }
206
+ catch (err) {
207
+ next(err);
208
+ }
209
+ });
210
+ /*
211
+ * Add a notification method to this user's account.
212
+ *
213
+ * The row lands UNVERIFIED and a verification code goes to the address itself,
214
+ * which is what keeps this from being a way to redirect somebody's pages: the
215
+ * verify endpoints refuse anybody but the row's owner, so the administrator who
216
+ * just typed the value in cannot complete it. See the service header.
217
+ */
218
+ router.post("/user-notification-method-admin/user/:userId", UserMiddleware.getUserMiddleware, async (req, res, next) => {
219
+ try {
220
+ const databaseProps = await CommonAPI.getDatabaseCommonInteractionProps(req);
221
+ const projectId = CommonAPI.assertAuthenticatedProjectMember(databaseProps);
222
+ /*
223
+ * Both gates run before the body is read. A route that validates a
224
+ * payload for a caller it is about to refuse has told that caller
225
+ * something about the payload format.
226
+ */
227
+ assertHasAnyPermission(databaseProps, MANAGE_PERMISSIONS);
228
+ const userId = readObjectIdParam(req, "userId");
229
+ await assertUserBelongsToProject(userId, projectId);
230
+ const methodType = readStringFromBody(req, "methodType");
231
+ const value = readStringFromBody(req, "value");
232
+ const created = await UserNotificationMethodAdminService.addMethodForUser({
233
+ projectId: projectId,
234
+ targetUserId: userId,
235
+ /*
236
+ * The actor the SERVER resolved, never anything from the body. This
237
+ * value names somebody in an audit entry and in a mail to the account
238
+ * holder, so a body-supplied one would let a caller sign their own
239
+ * change with a colleague's name.
240
+ */
241
+ actorUserId: databaseProps.userId,
242
+ methodType: methodType,
243
+ value: value,
244
+ props: databaseProps,
245
+ });
246
+ return Response.sendJsonObjectResponse(req, res, serializeMethod(created));
247
+ }
248
+ catch (err) {
249
+ next(err);
250
+ }
251
+ });
252
+ /*
253
+ * What removing this method would cost, before anybody confirms it.
254
+ *
255
+ * Read-only, and gated as a WRITE rather than as a read: the numbers it returns
256
+ * are about this user's rule coverage, and the only reason to ask for them is
257
+ * that you are about to delete something.
258
+ */
259
+ router.get("/user-notification-method-admin/user/:userId/:methodType/:methodId/deletion-impact", UserMiddleware.getUserMiddleware, async (req, res, next) => {
260
+ try {
261
+ const databaseProps = await CommonAPI.getDatabaseCommonInteractionProps(req);
262
+ const projectId = CommonAPI.assertAuthenticatedProjectMember(databaseProps);
263
+ assertHasAnyPermission(databaseProps, MANAGE_PERMISSIONS);
264
+ const userId = readObjectIdParam(req, "userId");
265
+ await assertUserBelongsToProject(userId, projectId);
266
+ const methodId = readObjectIdParam(req, "methodId");
267
+ const preview = await UserNotificationMethodAdminService.getDeletionPreview({
268
+ projectId: projectId,
269
+ targetUserId: userId,
270
+ methodType: req.params["methodType"] || "",
271
+ methodId: methodId,
272
+ });
273
+ return Response.sendJsonObjectResponse(req, res, preview);
274
+ }
275
+ catch (err) {
276
+ next(err);
277
+ }
278
+ });
279
+ /*
280
+ * Send the verification code again, to the device.
281
+ *
282
+ * Discloses nothing — the code goes to the address on the row, which is the one
283
+ * thing on it the administrator cannot read — and it is the lever that makes
284
+ * adding a method on somebody's behalf actually finish: "I added your work
285
+ * mobile, here is another code" rather than re-typing the number.
286
+ */
287
+ router.post("/user-notification-method-admin/user/:userId/:methodType/:methodId/resend-verification-code", UserMiddleware.getUserMiddleware, async (req, res, next) => {
288
+ try {
289
+ const databaseProps = await CommonAPI.getDatabaseCommonInteractionProps(req);
290
+ const projectId = CommonAPI.assertAuthenticatedProjectMember(databaseProps);
291
+ assertHasAnyPermission(databaseProps, MANAGE_PERMISSIONS);
292
+ const userId = readObjectIdParam(req, "userId");
293
+ await assertUserBelongsToProject(userId, projectId);
294
+ const methodId = readObjectIdParam(req, "methodId");
295
+ await UserNotificationMethodAdminService.resendVerificationCodeForUser({
296
+ projectId: projectId,
297
+ targetUserId: userId,
298
+ methodType: req.params["methodType"] || "",
299
+ methodId: methodId,
300
+ });
301
+ return Response.sendEmptySuccessResponse(req, res);
302
+ }
303
+ catch (err) {
304
+ next(err);
305
+ }
306
+ });
307
+ /*
308
+ * Remove one of this user's notification methods.
309
+ *
310
+ * DELETE rather than a POST to a /delete path, because it is one, and because
311
+ * the id it names is the only thing that identifies the row — there is no body
312
+ * to get out of step with the URL.
313
+ *
314
+ * Every rule pointing at this method goes with it (the foreign keys are all
315
+ * onDelete: "CASCADE"), which is why the preview route above exists and why the
316
+ * owner is always mailed about this one.
317
+ */
318
+ router.delete("/user-notification-method-admin/user/:userId/:methodType/:methodId", UserMiddleware.getUserMiddleware, async (req, res, next) => {
319
+ try {
320
+ const databaseProps = await CommonAPI.getDatabaseCommonInteractionProps(req);
321
+ const projectId = CommonAPI.assertAuthenticatedProjectMember(databaseProps);
322
+ assertHasAnyPermission(databaseProps, MANAGE_PERMISSIONS);
323
+ const userId = readObjectIdParam(req, "userId");
324
+ await assertUserBelongsToProject(userId, projectId);
325
+ const methodId = readObjectIdParam(req, "methodId");
326
+ await UserNotificationMethodAdminService.deleteMethodForUser({
327
+ projectId: projectId,
328
+ targetUserId: userId,
329
+ actorUserId: databaseProps.userId,
330
+ methodType: req.params["methodType"] || "",
331
+ methodId: methodId,
332
+ props: databaseProps,
333
+ });
334
+ return Response.sendEmptySuccessResponse(req, res);
335
+ }
336
+ catch (err) {
337
+ next(err);
338
+ }
339
+ });
340
+ export default router;
341
+ //# sourceMappingURL=UserNotificationMethodAdminAPI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserNotificationMethodAdminAPI.js","sourceRoot":"","sources":["../../../../Server/API/UserNotificationMethodAdminAPI.ts"],"names":[],"mappings":"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"}