@oneuptime/common 12.0.13 → 12.0.15

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 (561) hide show
  1. package/Models/DatabaseModels/GlobalOidc.ts +20 -0
  2. package/Models/DatabaseModels/GlobalSso.ts +20 -0
  3. package/Models/DatabaseModels/MarketingConversion.ts +19 -9
  4. package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +46 -0
  5. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
  6. package/Models/DatabaseModels/StatusPage.ts +7 -4
  7. package/Models/DatabaseModels/UserCall.ts +94 -3
  8. package/Models/DatabaseModels/UserEmail.ts +94 -3
  9. package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
  10. package/Models/DatabaseModels/UserPush.ts +37 -0
  11. package/Models/DatabaseModels/UserSMS.ts +94 -3
  12. package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
  13. package/Server/API/BaseAPI.ts +79 -14
  14. package/Server/API/StatusPageAPI.ts +29 -4
  15. package/Server/API/UserCallAPI.ts +53 -45
  16. package/Server/API/UserEmailAPI.ts +53 -44
  17. package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
  18. package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
  19. package/Server/API/UserPushAPI.ts +126 -2
  20. package/Server/API/UserSmsAPI.ts +53 -44
  21. package/Server/API/UserWhatsAppAPI.ts +53 -50
  22. package/Server/EnvironmentConfig.ts +7 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.ts +19 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.ts +40 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  29. package/Server/Middleware/SlackAuthorization.ts +43 -6
  30. package/Server/Middleware/UserAuthorization.ts +236 -26
  31. package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
  32. package/Server/Middleware/WhatsAppAuthorization.ts +43 -3
  33. package/Server/Services/AnalyticsDatabaseService.ts +169 -0
  34. package/Server/Services/DatabaseService.ts +101 -0
  35. package/Server/Services/GlobalOidcProjectService.ts +126 -1
  36. package/Server/Services/GlobalOidcService.ts +132 -0
  37. package/Server/Services/GlobalSsoProjectService.ts +126 -1
  38. package/Server/Services/GlobalSsoService.ts +132 -0
  39. package/Server/Services/LogAggregationService.ts +5 -0
  40. package/Server/Services/PushNotificationService.ts +127 -12
  41. package/Server/Services/TeamMemberService.ts +53 -13
  42. package/Server/Services/UserCallService.ts +55 -24
  43. package/Server/Services/UserEmailService.ts +83 -17
  44. package/Server/Services/UserIncomingCallNumberService.ts +49 -85
  45. package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
  46. package/Server/Services/UserNotificationRuleService.ts +26 -0
  47. package/Server/Services/UserPushService.ts +89 -0
  48. package/Server/Services/UserSmsService.ts +50 -17
  49. package/Server/Services/UserWhatsAppService.ts +48 -15
  50. package/Server/Types/Database/QueryHelper.ts +30 -0
  51. package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
  52. package/Server/Utils/ChannelVerification.ts +510 -0
  53. package/Server/Utils/CronTab.ts +73 -0
  54. package/Server/Utils/GlobalSsoAuthorization.ts +175 -0
  55. package/Server/Utils/Marketing/ConversionUploadProvider.ts +35 -5
  56. package/Server/Utils/Marketing/Providers/GoogleAds.ts +1 -1
  57. package/Server/Utils/Marketing/Providers/LinkedIn.ts +1 -1
  58. package/Server/Utils/Marketing/Providers/Meta.ts +1 -1
  59. package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +1 -1
  60. package/Server/Utils/Marketing/Providers/Reddit.ts +1 -1
  61. package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +48 -33
  62. package/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.ts +35 -30
  63. package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +33 -28
  64. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +475 -47
  65. package/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.ts +35 -30
  66. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +47 -44
  67. package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +33 -28
  68. package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +69 -40
  69. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +35 -29
  70. package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
  71. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +8 -0
  72. package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
  73. package/Server/Utils/Monitor/MonitorResource.ts +161 -21
  74. package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
  75. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
  76. package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
  77. package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
  78. package/Server/Utils/StatusPageContentSecurityPolicy.ts +56 -0
  79. package/Server/Utils/StatusPageCustomizationAccess.ts +117 -0
  80. package/Server/Utils/TotpAuth.ts +137 -9
  81. package/Server/Utils/UserRegistrationToken.ts +182 -0
  82. package/Server/Utils/VerificationCode.ts +134 -0
  83. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
  84. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
  85. package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
  86. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
  87. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
  88. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +28 -0
  89. package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
  90. package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
  91. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
  92. package/Tests/Server/API/StatusPageCustomizationOrigin.test.ts +348 -0
  93. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
  94. package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
  95. package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
  96. package/Tests/Server/API/UserSmsApi.test.ts +107 -14
  97. package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
  98. package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +265 -0
  99. package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +227 -0
  100. package/Tests/Server/Middleware/SlackAuthorization.test.ts +149 -0
  101. package/Tests/Server/Middleware/UserAuthorization.test.ts +27 -13
  102. package/Tests/Server/Middleware/UserAuthorizationGlobalSsoGovernance.test.ts +1455 -0
  103. package/Tests/Server/Middleware/UserAuthorizationSSOProvider.test.ts +91 -2
  104. package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
  105. package/Tests/Server/Middleware/WhatsAppAuthorization.test.ts +233 -0
  106. package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
  107. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
  108. package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
  109. package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
  110. package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
  111. package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
  112. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
  113. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +21 -8
  114. package/Tests/Server/Services/GlobalSsoProviderAuthorization.test.ts +1242 -0
  115. package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
  116. package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
  117. package/Tests/Server/Services/MonitorResourceProbeAgreementHydration.test.ts +459 -0
  118. package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +10 -0
  119. package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
  120. package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
  121. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
  122. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
  123. package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
  124. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
  125. package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
  126. package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
  127. package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
  128. package/Tests/Server/Types/AnalyticsDatabase/AggregateUtilBucketTimestamp.test.ts +416 -0
  129. package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
  130. package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
  131. package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
  132. package/Tests/Server/Types/Database/QueryHelperManyToManyAndEmptyValues.test.ts +551 -0
  133. package/Tests/Server/Types/Database/SelectUtil.test.ts +348 -0
  134. package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
  135. package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
  136. package/Tests/Server/Utils/Browser.test.ts +162 -0
  137. package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
  138. package/Tests/Server/Utils/CronTab.test.ts +116 -0
  139. package/Tests/Server/Utils/Express.test.ts +371 -0
  140. package/Tests/Server/Utils/GlobalSSOToken.test.ts +581 -0
  141. package/Tests/Server/Utils/GlobalSsoAuthorization.test.ts +1401 -0
  142. package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +254 -0
  143. package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +1 -1
  144. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaEvaluateOverTime.test.ts +508 -0
  145. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +30 -9
  146. package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
  147. package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
  148. package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +987 -0
  149. package/Tests/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.test.ts +916 -0
  150. package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
  151. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
  152. package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +382 -0
  153. package/Tests/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.test.ts +1219 -0
  154. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
  155. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
  156. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
  157. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
  158. package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +86 -0
  159. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
  160. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
  161. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
  162. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
  163. package/Tests/Server/Utils/StatusPageContentSecurityPolicy.test.ts +136 -0
  164. package/Tests/Server/Utils/StatusPageCustomizationAccess.test.ts +223 -0
  165. package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
  166. package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
  167. package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
  168. package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
  169. package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
  170. package/Tests/Types/Call/CallRequest.test.ts +189 -0
  171. package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
  172. package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
  173. package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
  174. package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
  175. package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
  176. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
  177. package/Tests/Types/Monitor/MonitorStepConfigHelpers.test.ts +165 -0
  178. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
  179. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
  180. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
  181. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
  182. package/Tests/Types/NetworkDevice/NetworkDeviceLinkRuleScope.test.ts +215 -0
  183. package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
  184. package/Tests/Types/TextRandomGeneration.test.ts +211 -0
  185. package/Tests/UI/Components/Button.test.tsx +175 -1
  186. package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
  187. package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
  188. package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
  189. package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
  190. package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
  191. package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
  192. package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
  193. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
  194. package/Tests/UI/Components/Forms/FormSubmitAnalytics.test.tsx +206 -0
  195. package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
  196. package/Tests/UI/Components/List.test.tsx +9 -2
  197. package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
  198. package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
  199. package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
  200. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
  201. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
  202. package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
  203. package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
  204. package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
  205. package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
  206. package/Tests/UI/Components/Skeleton.test.tsx +71 -0
  207. package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
  208. package/Tests/UI/Components/Tabs.test.tsx +24 -0
  209. package/Tests/UI/Components/Toast.test.tsx +130 -7
  210. package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
  211. package/Tests/UI/Utils/AIChatExport/ConversationMarkdown.test.ts +774 -0
  212. package/Tests/UI/Utils/AIChatExport/MarkdownBlocks.test.ts +791 -0
  213. package/Tests/UI/Utils/AIChatExport/MarkdownSafety.test.ts +544 -0
  214. package/Tests/UI/Utils/Dropdown.test.ts +423 -0
  215. package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
  216. package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
  217. package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
  218. package/Tests/Utils/API.test.ts +16 -2
  219. package/Tests/Utils/Analytics.test.ts +187 -0
  220. package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
  221. package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
  222. package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
  223. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +80 -0
  224. package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +1291 -0
  225. package/Tests/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.test.ts +214 -0
  226. package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
  227. package/Types/Email/EmailTemplateType.ts +1 -0
  228. package/Types/Marketing/MarketingConversion.ts +12 -0
  229. package/Types/Monitor/CriteriaFilter.ts +9 -0
  230. package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
  231. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
  232. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
  233. package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
  234. package/Types/NetworkDevice/NetworkDeviceLinkRuleScope.ts +51 -0
  235. package/Types/Permission.ts +35 -0
  236. package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
  237. package/Types/PushNotification/PushNotificationMessage.ts +15 -0
  238. package/Types/PushNotification/PushNotificationRequest.ts +8 -16
  239. package/Types/Service/ServiceLanguage.ts +144 -0
  240. package/Types/Text.ts +111 -19
  241. package/UI/Components/Button/Button.tsx +27 -14
  242. package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
  243. package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
  244. package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
  245. package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
  246. package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
  247. package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
  248. package/UI/Components/CommandPalette/Types.ts +49 -0
  249. package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
  250. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  251. package/UI/Components/Feed/FeedItem.tsx +1 -1
  252. package/UI/Components/FormModal/BasicFormModal.tsx +12 -0
  253. package/UI/Components/Forms/BasicForm.tsx +13 -1
  254. package/UI/Components/Forms/BasicModelForm.tsx +2 -1
  255. package/UI/Components/Forms/ModelForm.tsx +10 -1
  256. package/UI/Components/Forms/Utils/FormAnalyticsName.ts +39 -0
  257. package/UI/Components/List/List.tsx +37 -5
  258. package/UI/Components/List/ListSkeleton.tsx +54 -0
  259. package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
  260. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
  261. package/UI/Components/Modal/Modal.tsx +2 -2
  262. package/UI/Components/ModelFormModal/ModelFormModal.tsx +6 -1
  263. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  264. package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
  265. package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
  266. package/UI/Components/Navbar/NavBar.tsx +14 -1
  267. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
  268. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
  269. package/UI/Components/SideOver/SideOver.tsx +37 -2
  270. package/UI/Components/Skeleton/Skeleton.tsx +53 -0
  271. package/UI/Components/Table/Table.tsx +74 -44
  272. package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
  273. package/UI/Components/Tabs/Tab.tsx +1 -1
  274. package/UI/Components/Toast/Toast.tsx +118 -53
  275. package/UI/Components/Toast/ToastInit.tsx +82 -32
  276. package/UI/Styles/Theme.css +40 -0
  277. package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
  278. package/UI/Utils/ModelListCache.ts +188 -0
  279. package/UI/Utils/Project.ts +29 -0
  280. package/Utils/API.ts +6 -1
  281. package/Utils/Analytics.ts +55 -2
  282. package/Utils/Monitor/MonitorMetricType.ts +40 -0
  283. package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +587 -37
  284. package/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.ts +115 -0
  285. package/build/dist/Models/DatabaseModels/GlobalOidc.js +21 -0
  286. package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/GlobalSso.js +21 -0
  288. package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/MarketingConversion.js +20 -10
  290. package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +47 -0
  292. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
  294. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  295. package/build/dist/Models/DatabaseModels/StatusPage.js +4 -4
  296. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  297. package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
  298. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  299. package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
  300. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  301. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
  302. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
  303. package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
  304. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  305. package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
  306. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  307. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
  308. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  309. package/build/dist/Server/API/BaseAPI.js +69 -13
  310. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  311. package/build/dist/Server/API/StatusPageAPI.js +25 -4
  312. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  313. package/build/dist/Server/API/UserCallAPI.js +42 -38
  314. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  315. package/build/dist/Server/API/UserEmailAPI.js +42 -38
  316. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  317. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
  318. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  319. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
  320. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
  321. package/build/dist/Server/API/UserPushAPI.js +95 -2
  322. package/build/dist/Server/API/UserPushAPI.js.map +1 -1
  323. package/build/dist/Server/API/UserSmsAPI.js +42 -38
  324. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  325. package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
  326. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  327. package/build/dist/Server/EnvironmentConfig.js +6 -0
  328. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  329. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
  330. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
  331. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
  332. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
  333. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
  334. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
  335. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js +12 -0
  336. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js.map +1 -0
  337. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js +29 -0
  338. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js.map +1 -0
  339. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  340. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  341. package/build/dist/Server/Middleware/SlackAuthorization.js +28 -4
  342. package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
  343. package/build/dist/Server/Middleware/UserAuthorization.js +197 -22
  344. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  345. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
  346. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
  347. package/build/dist/Server/Middleware/WhatsAppAuthorization.js +32 -2
  348. package/build/dist/Server/Middleware/WhatsAppAuthorization.js.map +1 -1
  349. package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
  350. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  351. package/build/dist/Server/Services/DatabaseService.js +74 -0
  352. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  353. package/build/dist/Server/Services/GlobalOidcProjectService.js +105 -0
  354. package/build/dist/Server/Services/GlobalOidcProjectService.js.map +1 -1
  355. package/build/dist/Server/Services/GlobalOidcService.js +127 -0
  356. package/build/dist/Server/Services/GlobalOidcService.js.map +1 -1
  357. package/build/dist/Server/Services/GlobalSsoProjectService.js +105 -0
  358. package/build/dist/Server/Services/GlobalSsoProjectService.js.map +1 -1
  359. package/build/dist/Server/Services/GlobalSsoService.js +127 -0
  360. package/build/dist/Server/Services/GlobalSsoService.js.map +1 -1
  361. package/build/dist/Server/Services/LogAggregationService.js +5 -0
  362. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  363. package/build/dist/Server/Services/PushNotificationService.js +69 -30
  364. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  365. package/build/dist/Server/Services/TeamMemberService.js +43 -7
  366. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  367. package/build/dist/Server/Services/UserCallService.js +54 -22
  368. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  369. package/build/dist/Server/Services/UserEmailService.js +78 -17
  370. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  371. package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
  372. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
  373. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
  374. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
  375. package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
  376. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  377. package/build/dist/Server/Services/UserPushService.js +77 -0
  378. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  379. package/build/dist/Server/Services/UserSmsService.js +50 -17
  380. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  381. package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
  382. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  383. package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
  384. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  385. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
  386. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
  387. package/build/dist/Server/Utils/ChannelVerification.js +348 -0
  388. package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
  389. package/build/dist/Server/Utils/CronTab.js +66 -0
  390. package/build/dist/Server/Utils/CronTab.js.map +1 -1
  391. package/build/dist/Server/Utils/GlobalSsoAuthorization.js +112 -0
  392. package/build/dist/Server/Utils/GlobalSsoAuthorization.js.map +1 -0
  393. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +17 -1
  394. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -1
  395. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +1 -1
  396. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -1
  397. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +1 -1
  398. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -1
  399. package/build/dist/Server/Utils/Marketing/Providers/Meta.js +1 -1
  400. package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -1
  401. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +1 -1
  402. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -1
  403. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +1 -1
  404. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -1
  405. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +37 -35
  406. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
  407. package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js +21 -25
  408. package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js.map +1 -1
  409. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +20 -22
  410. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
  411. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +370 -42
  412. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  413. package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js +21 -25
  414. package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js.map +1 -1
  415. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +34 -37
  416. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  417. package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +21 -25
  418. package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
  419. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +64 -52
  420. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
  421. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +25 -29
  422. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  423. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
  424. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  425. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +8 -0
  426. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  427. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
  428. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  429. package/build/dist/Server/Utils/Monitor/MonitorResource.js +123 -23
  430. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  431. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
  432. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
  433. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
  434. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
  435. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
  436. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
  437. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  438. package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js +39 -0
  439. package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js.map +1 -0
  440. package/build/dist/Server/Utils/StatusPageCustomizationAccess.js +85 -0
  441. package/build/dist/Server/Utils/StatusPageCustomizationAccess.js.map +1 -0
  442. package/build/dist/Server/Utils/TotpAuth.js +127 -8
  443. package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
  444. package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
  445. package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
  446. package/build/dist/Server/Utils/VerificationCode.js +120 -0
  447. package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
  448. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  449. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  450. package/build/dist/Types/Marketing/MarketingConversion.js +10 -0
  451. package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -1
  452. package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
  453. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  454. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
  455. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  456. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
  457. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  458. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
  459. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  460. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
  461. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
  462. package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js +46 -0
  463. package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js.map +1 -0
  464. package/build/dist/Types/Permission.js +33 -0
  465. package/build/dist/Types/Permission.js.map +1 -1
  466. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
  467. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
  468. package/build/dist/Types/Service/ServiceLanguage.js +96 -0
  469. package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
  470. package/build/dist/Types/Text.js +82 -17
  471. package/build/dist/Types/Text.js.map +1 -1
  472. package/build/dist/UI/Components/Button/Button.js +22 -14
  473. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  474. package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
  475. package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
  476. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
  477. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
  478. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
  479. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
  480. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
  481. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
  482. package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
  483. package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
  484. package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
  485. package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
  486. package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
  487. package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
  488. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
  489. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
  490. package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
  491. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  492. package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
  493. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  494. package/build/dist/UI/Components/FormModal/BasicFormModal.js +2 -1
  495. package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
  496. package/build/dist/UI/Components/Forms/BasicForm.js +10 -1
  497. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  498. package/build/dist/UI/Components/Forms/BasicModelForm.js +2 -1
  499. package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
  500. package/build/dist/UI/Components/Forms/ModelForm.js +4 -1
  501. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  502. package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js +33 -0
  503. package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js.map +1 -0
  504. package/build/dist/UI/Components/List/List.js +19 -5
  505. package/build/dist/UI/Components/List/List.js.map +1 -1
  506. package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
  507. package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
  508. package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
  509. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
  510. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  511. package/build/dist/UI/Components/Modal/Modal.js +2 -2
  512. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +2 -1
  513. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  514. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  515. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  516. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
  517. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  518. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
  519. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  520. package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
  521. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  522. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
  523. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  524. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
  525. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  526. package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
  527. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  528. package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
  529. package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
  530. package/build/dist/UI/Components/Table/Table.js +35 -24
  531. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  532. package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
  533. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
  534. package/build/dist/UI/Components/Tabs/Tab.js +1 -1
  535. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  536. package/build/dist/UI/Components/Toast/Toast.js +77 -23
  537. package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
  538. package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
  539. package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
  540. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
  541. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  542. package/build/dist/UI/Utils/ModelListCache.js +126 -0
  543. package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
  544. package/build/dist/UI/Utils/Project.js +24 -1
  545. package/build/dist/UI/Utils/Project.js.map +1 -1
  546. package/build/dist/Utils/API.js +6 -1
  547. package/build/dist/Utils/API.js.map +1 -1
  548. package/build/dist/Utils/Analytics.js +50 -2
  549. package/build/dist/Utils/Analytics.js.map +1 -1
  550. package/build/dist/Utils/Monitor/MonitorMetricType.js +37 -0
  551. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  552. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +318 -37
  553. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -1
  554. package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js +87 -0
  555. package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js.map +1 -0
  556. package/jest.config.json +1 -1
  557. package/package.json +2 -3
  558. package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
  559. package/Tests/__mocks__/otpauth.js +0 -30
  560. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
  561. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
@@ -0,0 +1,470 @@
1
+ import FilterCondition from "../../../Types/Filter/FilterCondition";
2
+ import {
3
+ CheckOn,
4
+ CriteriaFilter,
5
+ FilterType,
6
+ } from "../../../Types/Monitor/CriteriaFilter";
7
+ import MonitorCriteria from "../../../Types/Monitor/MonitorCriteria";
8
+ import MonitorCriteriaInstance from "../../../Types/Monitor/MonitorCriteriaInstance";
9
+ import MonitorType from "../../../Types/Monitor/MonitorType";
10
+ import ObjectID from "../../../Types/ObjectID";
11
+
12
+ /*
13
+ * Incoming Request and Incoming Email monitors are push-driven: the sender
14
+ * decides when data arrives and what it says. Their out-of-the-box criteria
15
+ * therefore read the payload body rather than the arrival clock:
16
+ *
17
+ * offline -> body CONTAINS "error"
18
+ * online -> body DOES NOT CONTAIN "error"
19
+ *
20
+ * These tests pin that contract down (shape, wiring, incident/alert
21
+ * templates, validation, serialization) so the defaults cannot silently
22
+ * drift back to the old "received in the last 30 minutes" heartbeat check.
23
+ */
24
+
25
+ const ONLINE_STATUS_ID: ObjectID = new ObjectID("100000000000000000000011");
26
+ const OFFLINE_STATUS_ID: ObjectID = new ObjectID("100000000000000000000012");
27
+ const INCIDENT_SEVERITY_ID: ObjectID = new ObjectID("100000000000000000000013");
28
+ const ALERT_SEVERITY_ID: ObjectID = new ObjectID("100000000000000000000014");
29
+
30
+ const KEYWORD: string =
31
+ MonitorCriteriaInstance.DEFAULT_INCOMING_BODY_ERROR_KEYWORD;
32
+
33
+ interface IncomingMonitorCase {
34
+ label: string;
35
+ monitorType: MonitorType;
36
+ bodyCheckOn: CheckOn;
37
+ // How the body is named in the human-readable copy.
38
+ bodyLabel: string;
39
+ // The check the defaults deliberately no longer use.
40
+ retiredCheckOn: CheckOn;
41
+ }
42
+
43
+ const CASES: Array<IncomingMonitorCase> = [
44
+ {
45
+ label: "Incoming Request",
46
+ monitorType: MonitorType.IncomingRequest,
47
+ bodyCheckOn: CheckOn.RequestBody,
48
+ bodyLabel: "request body",
49
+ retiredCheckOn: CheckOn.IncomingRequest,
50
+ },
51
+ {
52
+ label: "Incoming Email",
53
+ monitorType: MonitorType.IncomingEmail,
54
+ bodyCheckOn: CheckOn.EmailBody,
55
+ bodyLabel: "email body",
56
+ retiredCheckOn: CheckOn.EmailReceivedAt,
57
+ },
58
+ ];
59
+
60
+ function buildOnline(
61
+ testCase: IncomingMonitorCase,
62
+ monitorName: string = "Payments API",
63
+ ): MonitorCriteriaInstance {
64
+ const instance: MonitorCriteriaInstance | null =
65
+ MonitorCriteriaInstance.getDefaultOnlineMonitorCriteriaInstance({
66
+ monitorType: testCase.monitorType,
67
+ monitorStatusId: ONLINE_STATUS_ID,
68
+ monitorName: monitorName,
69
+ });
70
+
71
+ if (!instance) {
72
+ throw new Error(`${testCase.label} has no default online criteria`);
73
+ }
74
+
75
+ return instance;
76
+ }
77
+
78
+ function buildOffline(
79
+ testCase: IncomingMonitorCase,
80
+ monitorName: string = "Payments API",
81
+ ): MonitorCriteriaInstance {
82
+ return MonitorCriteriaInstance.getDefaultOfflineMonitorCriteriaInstance({
83
+ monitorType: testCase.monitorType,
84
+ monitorStatusId: OFFLINE_STATUS_ID,
85
+ incidentSeverityId: INCIDENT_SEVERITY_ID,
86
+ alertSeverityId: ALERT_SEVERITY_ID,
87
+ monitorName: monitorName,
88
+ });
89
+ }
90
+
91
+ describe("Incoming monitor default criteria", () => {
92
+ describe("DEFAULT_INCOMING_BODY_ERROR_KEYWORD", () => {
93
+ test('is the lower-cased word "error"', () => {
94
+ expect(KEYWORD).toBe("error");
95
+ });
96
+ });
97
+
98
+ describe.each(CASES)(
99
+ "$label monitor",
100
+ (testCase: IncomingMonitorCase): void => {
101
+ describe("online criteria", () => {
102
+ test(`checks that the ${testCase.bodyLabel} does not contain the error keyword`, () => {
103
+ const instance: MonitorCriteriaInstance = buildOnline(testCase);
104
+
105
+ expect(instance.data?.filters).toHaveLength(1);
106
+
107
+ const filter: CriteriaFilter = instance.data!.filters[0]!;
108
+
109
+ expect(filter.checkOn).toBe(testCase.bodyCheckOn);
110
+ expect(filter.filterType).toBe(FilterType.NotContains);
111
+ expect(filter.value).toBe(KEYWORD);
112
+ });
113
+
114
+ test("no longer checks the arrival clock", () => {
115
+ const instance: MonitorCriteriaInstance = buildOnline(testCase);
116
+
117
+ const checkOns: Array<CheckOn> = instance.data!.filters.map(
118
+ (filter: CriteriaFilter) => {
119
+ return filter.checkOn;
120
+ },
121
+ );
122
+
123
+ expect(checkOns).not.toContain(testCase.retiredCheckOn);
124
+
125
+ const filterTypes: Array<FilterType | undefined> =
126
+ instance.data!.filters.map((filter: CriteriaFilter) => {
127
+ return filter.filterType;
128
+ });
129
+
130
+ expect(filterTypes).not.toContain(FilterType.RecievedInMinutes);
131
+ expect(filterTypes).not.toContain(FilterType.NotRecievedInMinutes);
132
+ });
133
+
134
+ test("flips the monitor status but never opens incidents or alerts", () => {
135
+ const instance: MonitorCriteriaInstance = buildOnline(testCase);
136
+
137
+ expect(instance.data?.changeMonitorStatus).toBe(true);
138
+ expect(instance.data?.createIncidents).toBe(false);
139
+ expect(instance.data?.createAlerts).toBe(false);
140
+ expect(instance.data?.incidents).toEqual([]);
141
+ expect(instance.data?.alerts).toEqual([]);
142
+ });
143
+
144
+ test("points at the online monitor status and uses an All filter condition", () => {
145
+ const instance: MonitorCriteriaInstance = buildOnline(testCase);
146
+
147
+ expect(instance.data?.monitorStatusId?.toString()).toBe(
148
+ ONLINE_STATUS_ID.toString(),
149
+ );
150
+ expect(instance.data?.filterCondition).toBe(FilterCondition.All);
151
+ });
152
+
153
+ test("names itself after the monitor and explains the body check", () => {
154
+ const instance: MonitorCriteriaInstance = buildOnline(
155
+ testCase,
156
+ "Checkout Webhook",
157
+ );
158
+
159
+ expect(instance.data?.name).toBe(
160
+ "Check if Checkout Webhook is online",
161
+ );
162
+ expect(instance.data?.description).toContain(testCase.bodyLabel);
163
+ expect(instance.data?.description).toContain("does not contain");
164
+ expect(instance.data?.description).toContain(KEYWORD);
165
+ });
166
+
167
+ test("gets a fresh id on every call", () => {
168
+ const first: MonitorCriteriaInstance = buildOnline(testCase);
169
+ const second: MonitorCriteriaInstance = buildOnline(testCase);
170
+
171
+ expect(first.data?.id).toBeTruthy();
172
+ expect(first.data?.id).not.toBe(second.data?.id);
173
+ });
174
+ });
175
+
176
+ describe("offline criteria", () => {
177
+ test(`checks that the ${testCase.bodyLabel} contains the error keyword`, () => {
178
+ const instance: MonitorCriteriaInstance = buildOffline(testCase);
179
+
180
+ expect(instance.data?.filters).toHaveLength(1);
181
+
182
+ const filter: CriteriaFilter = instance.data!.filters[0]!;
183
+
184
+ expect(filter.checkOn).toBe(testCase.bodyCheckOn);
185
+ expect(filter.filterType).toBe(FilterType.Contains);
186
+ expect(filter.value).toBe(KEYWORD);
187
+ });
188
+
189
+ test("no longer checks the arrival clock", () => {
190
+ const instance: MonitorCriteriaInstance = buildOffline(testCase);
191
+
192
+ const checkOns: Array<CheckOn> = instance.data!.filters.map(
193
+ (filter: CriteriaFilter) => {
194
+ return filter.checkOn;
195
+ },
196
+ );
197
+
198
+ expect(checkOns).not.toContain(testCase.retiredCheckOn);
199
+
200
+ const filterTypes: Array<FilterType | undefined> =
201
+ instance.data!.filters.map((filter: CriteriaFilter) => {
202
+ return filter.filterType;
203
+ });
204
+
205
+ expect(filterTypes).not.toContain(FilterType.NotRecievedInMinutes);
206
+ expect(filterTypes).not.toContain(FilterType.RecievedInMinutes);
207
+ });
208
+
209
+ test("opens an auto-resolving incident with the configured severity", () => {
210
+ const instance: MonitorCriteriaInstance = buildOffline(
211
+ testCase,
212
+ "Checkout Webhook",
213
+ );
214
+
215
+ expect(instance.data?.createIncidents).toBe(true);
216
+ expect(instance.data?.incidents).toHaveLength(1);
217
+
218
+ const incident: NonNullable<
219
+ typeof instance.data
220
+ >["incidents"][number] = instance.data!.incidents[0]!;
221
+
222
+ expect(incident.title).toBe("Checkout Webhook is offline");
223
+ expect(incident.autoResolveIncident).toBe(true);
224
+ expect(incident.incidentSeverityId?.toString()).toBe(
225
+ INCIDENT_SEVERITY_ID.toString(),
226
+ );
227
+ expect(incident.onCallPolicyIds).toEqual([]);
228
+ expect(incident.description).toContain(testCase.bodyLabel);
229
+ expect(incident.description).toContain(KEYWORD);
230
+ });
231
+
232
+ test("ships an alert template that stays switched off by default", () => {
233
+ const instance: MonitorCriteriaInstance = buildOffline(
234
+ testCase,
235
+ "Checkout Webhook",
236
+ );
237
+
238
+ expect(instance.data?.createAlerts).toBe(false);
239
+ expect(instance.data?.alerts).toHaveLength(1);
240
+
241
+ const alert: NonNullable<typeof instance.data>["alerts"][number] =
242
+ instance.data!.alerts[0]!;
243
+
244
+ expect(alert.title).toBe("Checkout Webhook is offline");
245
+ expect(alert.autoResolveAlert).toBe(true);
246
+ expect(alert.alertSeverityId?.toString()).toBe(
247
+ ALERT_SEVERITY_ID.toString(),
248
+ );
249
+ expect(alert.description).toContain(testCase.bodyLabel);
250
+ expect(alert.description).toContain(KEYWORD);
251
+ });
252
+
253
+ test("does not claim that nothing was received", () => {
254
+ const instance: MonitorCriteriaInstance = buildOffline(testCase);
255
+
256
+ expect(instance.data?.incidents[0]?.description).not.toContain(
257
+ "No email received",
258
+ );
259
+ expect(instance.data?.alerts[0]?.description).not.toContain(
260
+ "No email received",
261
+ );
262
+ });
263
+
264
+ test("points at the offline monitor status and uses an Any filter condition", () => {
265
+ const instance: MonitorCriteriaInstance = buildOffline(testCase);
266
+
267
+ expect(instance.data?.monitorStatusId?.toString()).toBe(
268
+ OFFLINE_STATUS_ID.toString(),
269
+ );
270
+ expect(instance.data?.filterCondition).toBe(FilterCondition.Any);
271
+ expect(instance.data?.changeMonitorStatus).toBe(true);
272
+ });
273
+
274
+ test("names itself after the monitor and explains the body check", () => {
275
+ const instance: MonitorCriteriaInstance = buildOffline(
276
+ testCase,
277
+ "Checkout Webhook",
278
+ );
279
+
280
+ expect(instance.data?.name).toBe(
281
+ "Check if Checkout Webhook is offline",
282
+ );
283
+ expect(instance.data?.description).toContain(testCase.bodyLabel);
284
+ expect(instance.data?.description).toContain("contains");
285
+ expect(instance.data?.description).toContain(KEYWORD);
286
+ });
287
+ });
288
+
289
+ describe("online and offline together", () => {
290
+ test("are exact complements of each other", () => {
291
+ const online: CriteriaFilter =
292
+ buildOnline(testCase).data!.filters[0]!;
293
+ const offline: CriteriaFilter =
294
+ buildOffline(testCase).data!.filters[0]!;
295
+
296
+ expect(online.checkOn).toBe(offline.checkOn);
297
+ expect(online.value).toBe(offline.value);
298
+ expect(online.filterType).toBe(FilterType.NotContains);
299
+ expect(offline.filterType).toBe(FilterType.Contains);
300
+ });
301
+
302
+ test("target different monitor statuses", () => {
303
+ expect(
304
+ buildOnline(testCase).data?.monitorStatusId?.toString(),
305
+ ).not.toBe(buildOffline(testCase).data?.monitorStatusId?.toString());
306
+ });
307
+
308
+ test("neither evaluates over a time window", () => {
309
+ for (const instance of [
310
+ buildOnline(testCase),
311
+ buildOffline(testCase),
312
+ ]) {
313
+ for (const filter of instance.data!.filters) {
314
+ expect(filter.evaluateOverTime).toBeFalsy();
315
+ expect(filter.evaluateOverTimeOptions).toBeUndefined();
316
+ }
317
+ }
318
+ });
319
+ });
320
+
321
+ describe("validation", () => {
322
+ test("the online criteria is valid", () => {
323
+ expect(
324
+ MonitorCriteriaInstance.getValidationError(
325
+ buildOnline(testCase),
326
+ testCase.monitorType,
327
+ ),
328
+ ).toBeNull();
329
+ });
330
+
331
+ test("the offline criteria is valid", () => {
332
+ expect(
333
+ MonitorCriteriaInstance.getValidationError(
334
+ buildOffline(testCase),
335
+ testCase.monitorType,
336
+ ),
337
+ ).toBeNull();
338
+ });
339
+
340
+ /*
341
+ * Contains / Not Contains are value-carrying filter types, so an
342
+ * empty default would trip getValidationError the moment a user
343
+ * opened the monitor form. Guard the keyword against being emptied.
344
+ */
345
+ test("a blank keyword would fail validation - so the default must not be blank", () => {
346
+ const instance: MonitorCriteriaInstance = buildOnline(testCase);
347
+ instance.data!.filters[0]!.value = "";
348
+
349
+ expect(
350
+ MonitorCriteriaInstance.getValidationError(
351
+ instance,
352
+ testCase.monitorType,
353
+ ),
354
+ ).toContain("Value is required");
355
+ expect(KEYWORD).not.toBe("");
356
+ });
357
+ });
358
+
359
+ describe("serialization", () => {
360
+ test("survives a toJSON / fromJSON round-trip", () => {
361
+ const original: MonitorCriteriaInstance = buildOffline(testCase);
362
+ const restored: MonitorCriteriaInstance =
363
+ MonitorCriteriaInstance.fromJSON(original.toJSON());
364
+
365
+ expect(restored.data?.filters[0]?.checkOn).toBe(testCase.bodyCheckOn);
366
+ expect(restored.data?.filters[0]?.filterType).toBe(
367
+ FilterType.Contains,
368
+ );
369
+ expect(restored.data?.filters[0]?.value).toBe(KEYWORD);
370
+ expect(restored.data?.filterCondition).toBe(FilterCondition.Any);
371
+ });
372
+
373
+ test("clone() is a deep copy of the body filter", () => {
374
+ const original: MonitorCriteriaInstance = buildOnline(testCase);
375
+ const clone: MonitorCriteriaInstance =
376
+ MonitorCriteriaInstance.clone(original);
377
+
378
+ clone.data!.filters[0]!.value = "mutated";
379
+
380
+ expect(original.data?.filters[0]?.value).toBe(KEYWORD);
381
+ });
382
+ });
383
+
384
+ describe("MonitorCriteria.getDefaultMonitorCriteria", () => {
385
+ test("composes the offline body check first and the online body check second", () => {
386
+ const criteria: MonitorCriteria =
387
+ MonitorCriteria.getDefaultMonitorCriteria({
388
+ monitorType: testCase.monitorType,
389
+ monitorName: "Payments API",
390
+ onlineMonitorStatusId: ONLINE_STATUS_ID,
391
+ offlineMonitorStatusId: OFFLINE_STATUS_ID,
392
+ defaultIncidentSeverityId: INCIDENT_SEVERITY_ID,
393
+ defaultAlertSeverityId: ALERT_SEVERITY_ID,
394
+ });
395
+
396
+ const instances: Array<MonitorCriteriaInstance> =
397
+ criteria.data!.monitorCriteriaInstanceArray;
398
+
399
+ expect(instances).toHaveLength(2);
400
+
401
+ expect(instances[0]?.data?.filters[0]?.checkOn).toBe(
402
+ testCase.bodyCheckOn,
403
+ );
404
+ expect(instances[0]?.data?.filters[0]?.filterType).toBe(
405
+ FilterType.Contains,
406
+ );
407
+ expect(instances[0]?.data?.monitorStatusId?.toString()).toBe(
408
+ OFFLINE_STATUS_ID.toString(),
409
+ );
410
+
411
+ expect(instances[1]?.data?.filters[0]?.checkOn).toBe(
412
+ testCase.bodyCheckOn,
413
+ );
414
+ expect(instances[1]?.data?.filters[0]?.filterType).toBe(
415
+ FilterType.NotContains,
416
+ );
417
+ expect(instances[1]?.data?.monitorStatusId?.toString()).toBe(
418
+ ONLINE_STATUS_ID.toString(),
419
+ );
420
+ });
421
+
422
+ test("passes validation as a whole", () => {
423
+ const criteria: MonitorCriteria =
424
+ MonitorCriteria.getDefaultMonitorCriteria({
425
+ monitorType: testCase.monitorType,
426
+ monitorName: "Payments API",
427
+ onlineMonitorStatusId: ONLINE_STATUS_ID,
428
+ offlineMonitorStatusId: OFFLINE_STATUS_ID,
429
+ defaultIncidentSeverityId: INCIDENT_SEVERITY_ID,
430
+ defaultAlertSeverityId: ALERT_SEVERITY_ID,
431
+ });
432
+
433
+ expect(
434
+ MonitorCriteria.getValidationError(criteria, testCase.monitorType),
435
+ ).toBeNull();
436
+ });
437
+ });
438
+ },
439
+ );
440
+
441
+ /*
442
+ * The two incoming monitor types now share a shape but must not share
443
+ * a CheckOn - an email monitor reading "Request Body" would evaluate
444
+ * nothing at all.
445
+ */
446
+ test("each incoming monitor type reads its own body field", () => {
447
+ const requestOnline: MonitorCriteriaInstance = buildOnline(CASES[0]!);
448
+ const emailOnline: MonitorCriteriaInstance = buildOnline(CASES[1]!);
449
+
450
+ expect(requestOnline.data?.filters[0]?.checkOn).toBe(CheckOn.RequestBody);
451
+ expect(emailOnline.data?.filters[0]?.checkOn).toBe(CheckOn.EmailBody);
452
+ });
453
+
454
+ /*
455
+ * Other push-driven monitor types are untouched by this change; a
456
+ * regression there would be easy to miss because they share the same
457
+ * builder.
458
+ */
459
+ test("does not change the Ping defaults", () => {
460
+ const online: MonitorCriteriaInstance | null =
461
+ MonitorCriteriaInstance.getDefaultOnlineMonitorCriteriaInstance({
462
+ monitorType: MonitorType.Ping,
463
+ monitorStatusId: ONLINE_STATUS_ID,
464
+ monitorName: "Gateway",
465
+ });
466
+
467
+ expect(online?.data?.filters[0]?.checkOn).toBe(CheckOn.IsOnline);
468
+ expect(online?.data?.filters[0]?.filterType).toBe(FilterType.True);
469
+ });
470
+ });
@@ -108,7 +108,7 @@ describe("MonitorCriteriaInstance", () => {
108
108
  );
109
109
  });
110
110
 
111
- test("IncomingRequest monitor uses a RecievedInMinutes filter", () => {
111
+ test("IncomingRequest monitor is online while the request body carries no error", () => {
112
112
  const instance: MonitorCriteriaInstance | null =
113
113
  MonitorCriteriaInstance.getDefaultOnlineMonitorCriteriaInstance({
114
114
  monitorType: MonitorType.IncomingRequest,
@@ -116,11 +116,13 @@ describe("MonitorCriteriaInstance", () => {
116
116
  monitorName: "Heartbeat",
117
117
  });
118
118
  expect(instance).not.toBeNull();
119
- expect(instance?.data?.filters[0]?.checkOn).toBe(CheckOn.IncomingRequest);
119
+ expect(instance?.data?.filters[0]?.checkOn).toBe(CheckOn.RequestBody);
120
120
  expect(instance?.data?.filters[0]?.filterType).toBe(
121
- FilterType.RecievedInMinutes,
121
+ FilterType.NotContains,
122
+ );
123
+ expect(instance?.data?.filters[0]?.value).toBe(
124
+ MonitorCriteriaInstance.DEFAULT_INCOMING_BODY_ERROR_KEYWORD,
122
125
  );
123
- expect(instance?.data?.filters[0]?.value).toBe(30);
124
126
  });
125
127
 
126
128
  test("Metrics monitor threads the first metric alias into options", () => {
@@ -0,0 +1,165 @@
1
+ import {
2
+ DEFAULT_MONITOR_REQUEST_TIMEOUT_IN_MS,
3
+ MAX_MONITOR_REQUEST_TIMEOUT_IN_MS,
4
+ clampMonitorRequestTimeoutInMs,
5
+ } from "../../../Types/Monitor/MonitorStep";
6
+ import { describe, expect, test } from "@jest/globals";
7
+
8
+ /*
9
+ * clampMonitorRequestTimeoutInMs constrains a per-step request timeout to the
10
+ * range the probe accepts. It has three decision points:
11
+ * 1. a falsy value (0 / NaN and, defensively, null / undefined) -> DEFAULT
12
+ * 2. a non-positive value (value <= 0) -> DEFAULT
13
+ * 3. a value above the cap (value > MAX) -> MAX
14
+ * anything else passes through unchanged. These tests walk each branch, both
15
+ * boundaries and the defensive coercions the callers can hand it.
16
+ *
17
+ * Note: with the current config DEFAULT and MAX happen to share the value
18
+ * 60000, so every assertion checks the constant that names the branch under
19
+ * test rather than the bare number, keeping the intent readable even if the
20
+ * two constants diverge later.
21
+ */
22
+
23
+ describe("clampMonitorRequestTimeoutInMs", () => {
24
+ describe("invalid / non-positive inputs fall back to the default", () => {
25
+ test("zero returns the default (caught by the falsy check)", () => {
26
+ const result: number = clampMonitorRequestTimeoutInMs(0);
27
+ expect(result).toBe(DEFAULT_MONITOR_REQUEST_TIMEOUT_IN_MS);
28
+ });
29
+
30
+ test("negative zero returns the default", () => {
31
+ const result: number = clampMonitorRequestTimeoutInMs(-0);
32
+ expect(result).toBe(DEFAULT_MONITOR_REQUEST_TIMEOUT_IN_MS);
33
+ });
34
+
35
+ test("NaN returns the default (NaN is falsy)", () => {
36
+ const result: number = clampMonitorRequestTimeoutInMs(NaN);
37
+ expect(result).toBe(DEFAULT_MONITOR_REQUEST_TIMEOUT_IN_MS);
38
+ });
39
+
40
+ test("a small negative value returns the default (value <= 0 branch)", () => {
41
+ const result: number = clampMonitorRequestTimeoutInMs(-1);
42
+ expect(result).toBe(DEFAULT_MONITOR_REQUEST_TIMEOUT_IN_MS);
43
+ });
44
+
45
+ test("a negative fraction returns the default", () => {
46
+ const result: number = clampMonitorRequestTimeoutInMs(-0.5);
47
+ expect(result).toBe(DEFAULT_MONITOR_REQUEST_TIMEOUT_IN_MS);
48
+ });
49
+
50
+ test("a large negative value returns the default, not a clamp", () => {
51
+ const result: number = clampMonitorRequestTimeoutInMs(-999999);
52
+ expect(result).toBe(DEFAULT_MONITOR_REQUEST_TIMEOUT_IN_MS);
53
+ });
54
+
55
+ test("negative Infinity returns the default", () => {
56
+ const result: number = clampMonitorRequestTimeoutInMs(-Infinity);
57
+ expect(result).toBe(DEFAULT_MONITOR_REQUEST_TIMEOUT_IN_MS);
58
+ });
59
+
60
+ /*
61
+ * The signature is typed as number, but real callers (JSON / DB rows,
62
+ * loosely typed UI state) can hand it a missing value. The falsy guard is
63
+ * what protects the probe here, so exercise it explicitly.
64
+ */
65
+ test("undefined coerced through the signature returns the default", () => {
66
+ const result: number = clampMonitorRequestTimeoutInMs(
67
+ undefined as unknown as number,
68
+ );
69
+ expect(result).toBe(DEFAULT_MONITOR_REQUEST_TIMEOUT_IN_MS);
70
+ });
71
+
72
+ test("null coerced through the signature returns the default", () => {
73
+ const result: number = clampMonitorRequestTimeoutInMs(
74
+ null as unknown as number,
75
+ );
76
+ expect(result).toBe(DEFAULT_MONITOR_REQUEST_TIMEOUT_IN_MS);
77
+ });
78
+ });
79
+
80
+ describe("in-range values pass through unchanged", () => {
81
+ test("the smallest positive integer is returned as-is", () => {
82
+ const result: number = clampMonitorRequestTimeoutInMs(1);
83
+ expect(result).toBe(1);
84
+ });
85
+
86
+ test("a fractional millisecond value is preserved", () => {
87
+ const result: number = clampMonitorRequestTimeoutInMs(1500.75);
88
+ expect(result).toBe(1500.75);
89
+ });
90
+
91
+ test("a typical mid-range timeout is returned unchanged", () => {
92
+ const result: number = clampMonitorRequestTimeoutInMs(30000);
93
+ expect(result).toBe(30000);
94
+ });
95
+
96
+ test("a value just below the cap is not clamped", () => {
97
+ const justUnder: number = MAX_MONITOR_REQUEST_TIMEOUT_IN_MS - 1;
98
+ const result: number = clampMonitorRequestTimeoutInMs(justUnder);
99
+ expect(result).toBe(justUnder);
100
+ });
101
+ });
102
+
103
+ describe("the upper boundary", () => {
104
+ test("a value exactly at the cap is returned, not clamped (> is strict)", () => {
105
+ const result: number = clampMonitorRequestTimeoutInMs(
106
+ MAX_MONITOR_REQUEST_TIMEOUT_IN_MS,
107
+ );
108
+ expect(result).toBe(MAX_MONITOR_REQUEST_TIMEOUT_IN_MS);
109
+ });
110
+
111
+ test("one millisecond over the cap is clamped down to the cap", () => {
112
+ const result: number = clampMonitorRequestTimeoutInMs(
113
+ MAX_MONITOR_REQUEST_TIMEOUT_IN_MS + 1,
114
+ );
115
+ expect(result).toBe(MAX_MONITOR_REQUEST_TIMEOUT_IN_MS);
116
+ });
117
+ });
118
+
119
+ describe("values well above the cap are clamped", () => {
120
+ test("a value far above the cap is clamped to the cap", () => {
121
+ const result: number = clampMonitorRequestTimeoutInMs(
122
+ MAX_MONITOR_REQUEST_TIMEOUT_IN_MS * 10,
123
+ );
124
+ expect(result).toBe(MAX_MONITOR_REQUEST_TIMEOUT_IN_MS);
125
+ });
126
+
127
+ test("positive Infinity is clamped to the cap", () => {
128
+ const result: number = clampMonitorRequestTimeoutInMs(Infinity);
129
+ expect(result).toBe(MAX_MONITOR_REQUEST_TIMEOUT_IN_MS);
130
+ });
131
+ });
132
+
133
+ describe("purity and stability", () => {
134
+ test("the same input always yields the same output", () => {
135
+ const first: number = clampMonitorRequestTimeoutInMs(45000);
136
+ const second: number = clampMonitorRequestTimeoutInMs(45000);
137
+ expect(first).toBe(second);
138
+ expect(first).toBe(45000);
139
+ });
140
+
141
+ test("the exported cap is a positive finite number", () => {
142
+ expect(Number.isFinite(MAX_MONITOR_REQUEST_TIMEOUT_IN_MS)).toBe(true);
143
+ expect(MAX_MONITOR_REQUEST_TIMEOUT_IN_MS).toBeGreaterThan(0);
144
+ });
145
+
146
+ test("the clamped result never exceeds the cap across a sweep", () => {
147
+ const samples: Array<number> = [
148
+ -5000,
149
+ 0,
150
+ 1,
151
+ 500,
152
+ 60000,
153
+ 60001,
154
+ 250000,
155
+ Infinity,
156
+ NaN,
157
+ ];
158
+ for (const sample of samples) {
159
+ const result: number = clampMonitorRequestTimeoutInMs(sample);
160
+ expect(result).toBeLessThanOrEqual(MAX_MONITOR_REQUEST_TIMEOUT_IN_MS);
161
+ expect(result).toBeGreaterThan(0);
162
+ }
163
+ });
164
+ });
165
+ });