@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,248 @@
1
+ import crypto from "crypto";
2
+
3
+ /*
4
+ * A stand-in for the authenticator app on the user's phone.
5
+ *
6
+ * Every function here is derived from RFC 4648 (base32), RFC 4226 (HOTP) and
7
+ * RFC 6238 (TOTP) using Node's own crypto primitives. Nothing in this file
8
+ * imports `otpauth`, and that is the entire point: the server verifies with
9
+ * `otpauth`, so a test that also generates its expected codes with `otpauth`
10
+ * proves only that the library agrees with itself. It would have passed
11
+ * happily throughout issue #3275, while every user with Google Authenticator
12
+ * was locked out.
13
+ *
14
+ * The most useful thing in here is `googleAuthenticatorCode`, which models the
15
+ * behaviour that caused that bug: real phone apps parse the otpauth:// URI,
16
+ * IGNORE its `algorithm` parameter, and compute SHA1 regardless.
17
+ */
18
+
19
+ const BASE32_ALPHABET: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
20
+
21
+ export const DEFAULT_DIGITS: number = 6;
22
+ export const DEFAULT_PERIOD_IN_SECONDS: number = 30;
23
+
24
+ /** The algorithm a phone app uses no matter what the QR code claims. */
25
+ export const PHONE_APP_ALGORITHM: string = "SHA1";
26
+
27
+ export type Base32EncodeFunction = (bytes: Buffer) => string;
28
+
29
+ export const base32Encode: Base32EncodeFunction = (bytes: Buffer): string => {
30
+ let bits: string = "";
31
+
32
+ for (const byte of bytes) {
33
+ bits += byte.toString(2).padStart(8, "0");
34
+ }
35
+
36
+ let output: string = "";
37
+
38
+ for (let i: number = 0; i < bits.length; i += 5) {
39
+ const chunk: string = bits.slice(i, i + 5).padEnd(5, "0");
40
+ output += BASE32_ALPHABET[parseInt(chunk, 2)];
41
+ }
42
+
43
+ return output;
44
+ };
45
+
46
+ export type Base32DecodeFunction = (encoded: string) => Buffer;
47
+
48
+ export const base32Decode: Base32DecodeFunction = (encoded: string): Buffer => {
49
+ let bits: string = "";
50
+
51
+ for (const character of encoded.replace(/[=]+$/, "").toUpperCase()) {
52
+ const value: number = BASE32_ALPHABET.indexOf(character);
53
+
54
+ if (value === -1) {
55
+ throw new Error(`Not base32: ${character}`);
56
+ }
57
+
58
+ bits += value.toString(2).padStart(5, "0");
59
+ }
60
+
61
+ const bytes: Array<number> = [];
62
+
63
+ for (let i: number = 0; i + 8 <= bits.length; i += 8) {
64
+ bytes.push(parseInt(bits.slice(i, i + 8), 2));
65
+ }
66
+
67
+ return Buffer.from(bytes);
68
+ };
69
+
70
+ /*
71
+ * HOTP, RFC 4226 section 5.3: HMAC the 8-byte big-endian counter under the
72
+ * shared key, take the low nibble of the last byte as an offset, read a
73
+ * big-endian 31-bit integer from there, reduce modulo 10^digits.
74
+ */
75
+ export type HotpFunction = (data: {
76
+ key: Buffer;
77
+ counter: number;
78
+ algorithm: string;
79
+ digits: number;
80
+ }) => string;
81
+
82
+ export const hotp: HotpFunction = (data: {
83
+ key: Buffer;
84
+ counter: number;
85
+ algorithm: string;
86
+ digits: number;
87
+ }): string => {
88
+ const counterBytes: Buffer = Buffer.alloc(8);
89
+ counterBytes.writeBigUInt64BE(BigInt(data.counter));
90
+
91
+ const digest: Buffer = crypto
92
+ .createHmac(data.algorithm.toLowerCase(), data.key)
93
+ .update(counterBytes)
94
+ .digest();
95
+
96
+ const offset: number = digest[digest.length - 1]! & 0x0f;
97
+
98
+ const binary: number =
99
+ ((digest[offset]! & 0x7f) << 24) |
100
+ ((digest[offset + 1]! & 0xff) << 16) |
101
+ ((digest[offset + 2]! & 0xff) << 8) |
102
+ (digest[offset + 3]! & 0xff);
103
+
104
+ return (binary % 10 ** data.digits).toString().padStart(data.digits, "0");
105
+ };
106
+
107
+ /*
108
+ * TOTP: HOTP with the counter derived from the clock (RFC 6238 section 4).
109
+ */
110
+ export type AuthenticatorCodeFunction = (data: {
111
+ secretBase32: string;
112
+ algorithm?: string | undefined;
113
+ digits?: number | undefined;
114
+ periodInSeconds?: number | undefined;
115
+ atUnixSeconds?: number | undefined;
116
+ }) => string;
117
+
118
+ export const authenticatorCode: AuthenticatorCodeFunction = (data: {
119
+ secretBase32: string;
120
+ algorithm?: string | undefined;
121
+ digits?: number | undefined;
122
+ periodInSeconds?: number | undefined;
123
+ atUnixSeconds?: number | undefined;
124
+ }): string => {
125
+ const period: number = data.periodInSeconds || DEFAULT_PERIOD_IN_SECONDS;
126
+
127
+ const seconds: number =
128
+ data.atUnixSeconds === undefined
129
+ ? Math.floor(Date.now() / 1000)
130
+ : data.atUnixSeconds;
131
+
132
+ return hotp({
133
+ key: base32Decode(data.secretBase32),
134
+ counter: Math.floor(seconds / period),
135
+ algorithm: data.algorithm || PHONE_APP_ALGORITHM,
136
+ digits: data.digits === undefined ? DEFAULT_DIGITS : data.digits,
137
+ });
138
+ };
139
+
140
+ export type OtpauthUriParams = {
141
+ secret: string;
142
+ algorithm: string;
143
+ digits: number;
144
+ periodInSeconds: number;
145
+ issuer: string | null;
146
+ };
147
+
148
+ export type ParseOtpauthUriFunction = (uri: string) => OtpauthUriParams;
149
+
150
+ export const parseOtpauthUri: ParseOtpauthUriFunction = (
151
+ uri: string,
152
+ ): OtpauthUriParams => {
153
+ const params: URLSearchParams = new URLSearchParams(
154
+ uri.slice(uri.indexOf("?") + 1),
155
+ );
156
+
157
+ return {
158
+ secret: params.get("secret") || "",
159
+ algorithm: params.get("algorithm") || PHONE_APP_ALGORITHM,
160
+ digits: parseInt(params.get("digits") || String(DEFAULT_DIGITS), 10),
161
+ periodInSeconds: parseInt(
162
+ params.get("period") || String(DEFAULT_PERIOD_IN_SECONDS),
163
+ 10,
164
+ ),
165
+ issuer: params.get("issuer"),
166
+ };
167
+ };
168
+
169
+ /*
170
+ * What an app that honours every parameter in the URI shows — 1Password,
171
+ * Bitwarden, Aegis, FreeOTP.
172
+ */
173
+ export type CodeFromUriFunction = (
174
+ uri: string,
175
+ atUnixSeconds?: number,
176
+ ) => string;
177
+
178
+ export const conformingAppCode: CodeFromUriFunction = (
179
+ uri: string,
180
+ atUnixSeconds?: number,
181
+ ): string => {
182
+ const params: OtpauthUriParams = parseOtpauthUri(uri);
183
+
184
+ return authenticatorCode({
185
+ secretBase32: params.secret,
186
+ algorithm: params.algorithm,
187
+ digits: params.digits,
188
+ periodInSeconds: params.periodInSeconds,
189
+ atUnixSeconds: atUnixSeconds,
190
+ });
191
+ };
192
+
193
+ /*
194
+ * What Google Authenticator shows: the secret from the URI, but SHA1 whatever
195
+ * the URI says. This is the function that reproduces issue #3275 — hand it a
196
+ * SHA256 URI and the code it returns is the one the user typed in and the
197
+ * server rejected.
198
+ */
199
+ export const googleAuthenticatorCode: CodeFromUriFunction = (
200
+ uri: string,
201
+ atUnixSeconds?: number,
202
+ ): string => {
203
+ const params: OtpauthUriParams = parseOtpauthUri(uri);
204
+
205
+ return authenticatorCode({
206
+ secretBase32: params.secret,
207
+ algorithm: PHONE_APP_ALGORITHM,
208
+ digits: params.digits,
209
+ periodInSeconds: params.periodInSeconds,
210
+ atUnixSeconds: atUnixSeconds,
211
+ });
212
+ };
213
+
214
+ /*
215
+ * The otpauth:// URI a server hands to a QR code, built by hand so a test can
216
+ * produce the exact shape the OLD OneUptime code used to emit.
217
+ */
218
+ export type BuildOtpauthUriFunction = (data: {
219
+ secret: string;
220
+ label: string;
221
+ issuer?: string | undefined;
222
+ algorithm?: string | undefined;
223
+ digits?: number | undefined;
224
+ periodInSeconds?: number | undefined;
225
+ }) => string;
226
+
227
+ export const buildOtpauthUri: BuildOtpauthUriFunction = (data: {
228
+ secret: string;
229
+ label: string;
230
+ issuer?: string | undefined;
231
+ algorithm?: string | undefined;
232
+ digits?: number | undefined;
233
+ periodInSeconds?: number | undefined;
234
+ }): string => {
235
+ const issuer: string = data.issuer || "OneUptime";
236
+
237
+ const query: string = [
238
+ `issuer=${encodeURIComponent(issuer)}`,
239
+ `secret=${data.secret}`,
240
+ `algorithm=${data.algorithm || PHONE_APP_ALGORITHM}`,
241
+ `digits=${data.digits === undefined ? DEFAULT_DIGITS : data.digits}`,
242
+ `period=${data.periodInSeconds || DEFAULT_PERIOD_IN_SECONDS}`,
243
+ ].join("&");
244
+
245
+ return `otpauth://totp/${encodeURIComponent(issuer)}:${encodeURIComponent(
246
+ data.label,
247
+ )}?${query}`;
248
+ };
@@ -0,0 +1,416 @@
1
+ import { AggregateUtil } from "../../../../Server/Types/AnalyticsDatabase/AggregateBy";
2
+ import AggregationInterval from "../../../../Types/BaseDatabase/AggregationInterval";
3
+ import { describe, expect, it } from "@jest/globals";
4
+
5
+ /*
6
+ * AggregateUtil is the server's single source of truth for turning a query
7
+ * window into an aggregation bucket size and for compiling that bucket into a
8
+ * ClickHouse timestamp expression. The tests below exercise the real branches:
9
+ *
10
+ * - getAggregationInterval: window-derived tier ladder, its <=-inclusive
11
+ * boundaries, and the explicit-override precedence (including Total, which
12
+ * the window picker itself never returns, and invalid overrides that fall
13
+ * through to the window).
14
+ * - isTotalAggregation: the Total-vs-everything-else predicate.
15
+ * - buildBucketTimestampExpression: the sub-hour toStartOfInterval tiers vs
16
+ * the lowercased date_trunc default, plus raw expression interpolation.
17
+ * - buildBucketTimestampSelect: the Total min() shape vs the aliased bucket
18
+ * expression it delegates to.
19
+ *
20
+ * Everything is deterministic: getAggregationInterval only reads the numeric
21
+ * millisecond diff between the two dates, so windows are built from a fixed
22
+ * epoch anchor plus an exact millisecond span.
23
+ */
24
+
25
+ /*
26
+ * Fixed anchor for every window. getAggregationInterval depends only on
27
+ * endDate - startDate, so the absolute instant is irrelevant; pinning it makes
28
+ * the boundary arithmetic obvious.
29
+ */
30
+ const ANCHOR_MS: number = 0;
31
+
32
+ /*
33
+ * Tier upper bounds, copied from the implementation so a change in the ladder
34
+ * is caught here rather than silently re-tiering every chart. Each value is the
35
+ * largest diff (inclusive) that still resolves to the tier it labels.
36
+ */
37
+ const THREE_HOURS_MS: number = 1000 * 60 * 60 * 3;
38
+ const TWELVE_HOURS_MS: number = 1000 * 60 * 60 * 12;
39
+ const TWENTY_FOUR_HOURS_MS: number = 1000 * 60 * 60 * 24;
40
+ const THREE_DAYS_MS: number = 1000 * 60 * 60 * 24 * 3;
41
+ const SEVEN_DAYS_MS: number = 1000 * 60 * 60 * 24 * 7;
42
+ const SIX_WEEKS_MS: number = 1000 * 60 * 60 * 24 * 7 * 6;
43
+ const SIX_MONTHS_MS: number = 1000 * 60 * 60 * 24 * 30 * 6;
44
+ const SIX_YEARS_MS: number = 1000 * 60 * 60 * 24 * 365 * 6;
45
+
46
+ function intervalForDiff(
47
+ diffMs: number,
48
+ aggregationInterval?: AggregationInterval,
49
+ ): AggregationInterval {
50
+ const startDate: Date = new Date(ANCHOR_MS);
51
+ const endDate: Date = new Date(ANCHOR_MS + diffMs);
52
+ return AggregateUtil.getAggregationInterval({
53
+ startDate,
54
+ endDate,
55
+ aggregationInterval,
56
+ });
57
+ }
58
+
59
+ describe("AggregateUtil.getAggregationInterval window-derived ladder", () => {
60
+ it("returns Minute for a zero-length window", () => {
61
+ const result: AggregationInterval = intervalForDiff(0);
62
+ expect(result).toBe(AggregationInterval.Minute);
63
+ });
64
+
65
+ it("returns Minute for a negative (end-before-start) window", () => {
66
+ /*
67
+ * A malformed window makes the diff negative, which is still <= every
68
+ * upper bound, so it collapses to the finest tier rather than throwing.
69
+ */
70
+ const result: AggregationInterval = intervalForDiff(-1000 * 60 * 60);
71
+ expect(result).toBe(AggregationInterval.Minute);
72
+ });
73
+
74
+ it("never returns Total from the window derivation (huge window -> Year)", () => {
75
+ const result: AggregationInterval = intervalForDiff(SIX_YEARS_MS + 1);
76
+ expect(result).toBe(AggregationInterval.Year);
77
+ expect(result).not.toBe(AggregationInterval.Total);
78
+ });
79
+
80
+ type LadderCase = {
81
+ label: string;
82
+ diffMs: number;
83
+ expected: AggregationInterval;
84
+ };
85
+
86
+ /*
87
+ * Each tier is probed at three points: comfortably inside the tier, exactly
88
+ * on its inclusive upper bound (must stay in the tier), and one millisecond
89
+ * past it (must roll to the next coarser tier). The last pair proves the
90
+ * ladder uses <= and not <.
91
+ */
92
+ const ladderCases: Array<LadderCase> = [
93
+ {
94
+ label: "1 hour -> Minute",
95
+ diffMs: 1000 * 60 * 60,
96
+ expected: AggregationInterval.Minute,
97
+ },
98
+ {
99
+ label: "exactly 3 hours -> Minute (inclusive bound)",
100
+ diffMs: THREE_HOURS_MS,
101
+ expected: AggregationInterval.Minute,
102
+ },
103
+ {
104
+ label: "3 hours + 1ms -> FiveMinutes",
105
+ diffMs: THREE_HOURS_MS + 1,
106
+ expected: AggregationInterval.FiveMinutes,
107
+ },
108
+ {
109
+ label: "exactly 12 hours -> FiveMinutes (inclusive bound)",
110
+ diffMs: TWELVE_HOURS_MS,
111
+ expected: AggregationInterval.FiveMinutes,
112
+ },
113
+ {
114
+ label: "12 hours + 1ms -> FifteenMinutes",
115
+ diffMs: TWELVE_HOURS_MS + 1,
116
+ expected: AggregationInterval.FifteenMinutes,
117
+ },
118
+ {
119
+ label: "exactly 24 hours -> FifteenMinutes (inclusive bound)",
120
+ diffMs: TWENTY_FOUR_HOURS_MS,
121
+ expected: AggregationInterval.FifteenMinutes,
122
+ },
123
+ {
124
+ label: "24 hours + 1ms -> ThirtyMinutes",
125
+ diffMs: TWENTY_FOUR_HOURS_MS + 1,
126
+ expected: AggregationInterval.ThirtyMinutes,
127
+ },
128
+ {
129
+ label: "exactly 3 days -> ThirtyMinutes (inclusive bound)",
130
+ diffMs: THREE_DAYS_MS,
131
+ expected: AggregationInterval.ThirtyMinutes,
132
+ },
133
+ {
134
+ label: "3 days + 1ms -> Hour",
135
+ diffMs: THREE_DAYS_MS + 1,
136
+ expected: AggregationInterval.Hour,
137
+ },
138
+ {
139
+ label: "exactly 7 days -> Hour (inclusive bound)",
140
+ diffMs: SEVEN_DAYS_MS,
141
+ expected: AggregationInterval.Hour,
142
+ },
143
+ {
144
+ label: "7 days + 1ms -> Day",
145
+ diffMs: SEVEN_DAYS_MS + 1,
146
+ expected: AggregationInterval.Day,
147
+ },
148
+ {
149
+ label: "exactly 6 weeks -> Day (inclusive bound)",
150
+ diffMs: SIX_WEEKS_MS,
151
+ expected: AggregationInterval.Day,
152
+ },
153
+ {
154
+ label: "6 weeks + 1ms -> Week",
155
+ diffMs: SIX_WEEKS_MS + 1,
156
+ expected: AggregationInterval.Week,
157
+ },
158
+ {
159
+ label: "exactly 6 months -> Week (inclusive bound)",
160
+ diffMs: SIX_MONTHS_MS,
161
+ expected: AggregationInterval.Week,
162
+ },
163
+ {
164
+ label: "6 months + 1ms -> Month",
165
+ diffMs: SIX_MONTHS_MS + 1,
166
+ expected: AggregationInterval.Month,
167
+ },
168
+ {
169
+ label: "exactly 6 years -> Month (inclusive bound)",
170
+ diffMs: SIX_YEARS_MS,
171
+ expected: AggregationInterval.Month,
172
+ },
173
+ {
174
+ label: "6 years + 1ms -> Year",
175
+ diffMs: SIX_YEARS_MS + 1,
176
+ expected: AggregationInterval.Year,
177
+ },
178
+ ];
179
+
180
+ it.each(ladderCases)(
181
+ "resolves $label",
182
+ ({ diffMs, expected }: LadderCase) => {
183
+ const result: AggregationInterval = intervalForDiff(diffMs);
184
+ expect(result).toBe(expected);
185
+ },
186
+ );
187
+ });
188
+
189
+ describe("AggregateUtil.getAggregationInterval explicit override precedence", () => {
190
+ it("returns a valid override verbatim, ignoring the (finer) window tier", () => {
191
+ /*
192
+ * A 1-hour window would derive Minute, but the override pins Year, proving
193
+ * the override short-circuits the window derivation entirely.
194
+ */
195
+ const result: AggregationInterval = intervalForDiff(
196
+ 1000 * 60 * 60,
197
+ AggregationInterval.Year,
198
+ );
199
+ expect(result).toBe(AggregationInterval.Year);
200
+ });
201
+
202
+ it("returns a valid override verbatim, ignoring the (coarser) window tier", () => {
203
+ const result: AggregationInterval = intervalForDiff(
204
+ SIX_YEARS_MS + 1,
205
+ AggregationInterval.Minute,
206
+ );
207
+ expect(result).toBe(AggregationInterval.Minute);
208
+ });
209
+
210
+ it("honours a Total override even though the window picker never yields Total", () => {
211
+ const result: AggregationInterval = intervalForDiff(
212
+ 1000 * 60 * 60,
213
+ AggregationInterval.Total,
214
+ );
215
+ expect(result).toBe(AggregationInterval.Total);
216
+ });
217
+
218
+ it("falls through to the window tier when the override is not a real enum value", () => {
219
+ /*
220
+ * Object.values(AggregationInterval).includes(...) rejects an unknown
221
+ * string, so the derivation runs and a 1-hour window resolves to Minute.
222
+ */
223
+ const bogusOverride: AggregationInterval =
224
+ "NotARealInterval" as AggregationInterval;
225
+ const result: AggregationInterval = intervalForDiff(
226
+ 1000 * 60 * 60,
227
+ bogusOverride,
228
+ );
229
+ expect(result).toBe(AggregationInterval.Minute);
230
+ });
231
+
232
+ it("preserves every enum value when passed as an explicit override", () => {
233
+ const allIntervals: Array<AggregationInterval> =
234
+ Object.values(AggregationInterval);
235
+ for (const interval of allIntervals) {
236
+ const result: AggregationInterval = intervalForDiff(
237
+ 1000 * 60 * 60,
238
+ interval,
239
+ );
240
+ expect(result).toBe(interval);
241
+ }
242
+ });
243
+ });
244
+
245
+ describe("AggregateUtil.isTotalAggregation", () => {
246
+ it("is true only for Total", () => {
247
+ expect(AggregateUtil.isTotalAggregation(AggregationInterval.Total)).toBe(
248
+ true,
249
+ );
250
+ });
251
+
252
+ it("is false for every non-Total interval", () => {
253
+ const nonTotalIntervals: Array<AggregationInterval> = Object.values(
254
+ AggregationInterval,
255
+ ).filter((interval: AggregationInterval) => {
256
+ return interval !== AggregationInterval.Total;
257
+ });
258
+
259
+ for (const interval of nonTotalIntervals) {
260
+ expect(AggregateUtil.isTotalAggregation(interval)).toBe(false);
261
+ }
262
+ });
263
+ });
264
+
265
+ describe("AggregateUtil.buildBucketTimestampExpression", () => {
266
+ const COL: string = "createdAt";
267
+
268
+ it("compiles FiveMinutes to a 5 MINUTE toStartOfInterval", () => {
269
+ const result: string = AggregateUtil.buildBucketTimestampExpression(
270
+ AggregationInterval.FiveMinutes,
271
+ COL,
272
+ );
273
+ expect(result).toBe(`toStartOfInterval(${COL}, INTERVAL 5 MINUTE)`);
274
+ });
275
+
276
+ it("compiles FifteenMinutes to a 15 MINUTE toStartOfInterval", () => {
277
+ const result: string = AggregateUtil.buildBucketTimestampExpression(
278
+ AggregationInterval.FifteenMinutes,
279
+ COL,
280
+ );
281
+ expect(result).toBe(`toStartOfInterval(${COL}, INTERVAL 15 MINUTE)`);
282
+ });
283
+
284
+ it("compiles ThirtyMinutes to a 30 MINUTE toStartOfInterval", () => {
285
+ const result: string = AggregateUtil.buildBucketTimestampExpression(
286
+ AggregationInterval.ThirtyMinutes,
287
+ COL,
288
+ );
289
+ expect(result).toBe(`toStartOfInterval(${COL}, INTERVAL 30 MINUTE)`);
290
+ });
291
+
292
+ type DefaultCase = {
293
+ interval: AggregationInterval;
294
+ unit: string;
295
+ };
296
+
297
+ /*
298
+ * The default branch lowercases the enum value into both the date_trunc unit
299
+ * and the INTERVAL 1 <unit> guard. These calendar units happen to be valid
300
+ * ClickHouse units, which is exactly why they route through the default arm.
301
+ */
302
+ const defaultCases: Array<DefaultCase> = [
303
+ { interval: AggregationInterval.Minute, unit: "minute" },
304
+ { interval: AggregationInterval.Hour, unit: "hour" },
305
+ { interval: AggregationInterval.Day, unit: "day" },
306
+ { interval: AggregationInterval.Week, unit: "week" },
307
+ { interval: AggregationInterval.Month, unit: "month" },
308
+ { interval: AggregationInterval.Year, unit: "year" },
309
+ ];
310
+
311
+ it.each(defaultCases)(
312
+ "compiles $interval via the lowercased date_trunc default",
313
+ ({ interval, unit }: DefaultCase) => {
314
+ const result: string = AggregateUtil.buildBucketTimestampExpression(
315
+ interval,
316
+ COL,
317
+ );
318
+ expect(result).toBe(
319
+ `date_trunc('${unit}', toStartOfInterval(${COL}, INTERVAL 1 ${unit}))`,
320
+ );
321
+ },
322
+ );
323
+
324
+ it("routes Total through the default branch as a lowercased unit in isolation", () => {
325
+ /*
326
+ * buildBucketTimestampSelect short-circuits Total before ever calling this
327
+ * function, but called directly Total falls into the default arm and is
328
+ * lowercased like any other value. This pins that isolated behavior so a
329
+ * future refactor cannot change it unnoticed.
330
+ */
331
+ const result: string = AggregateUtil.buildBucketTimestampExpression(
332
+ AggregationInterval.Total,
333
+ COL,
334
+ );
335
+ expect(result).toBe(
336
+ `date_trunc('total', toStartOfInterval(${COL}, INTERVAL 1 total))`,
337
+ );
338
+ });
339
+
340
+ it("interpolates a compound builder expression verbatim in the sub-hour branch", () => {
341
+ const expression: string = "toDateTime(t.created_at)";
342
+ const result: string = AggregateUtil.buildBucketTimestampExpression(
343
+ AggregationInterval.FiveMinutes,
344
+ expression,
345
+ );
346
+ expect(result).toBe(`toStartOfInterval(${expression}, INTERVAL 5 MINUTE)`);
347
+ });
348
+
349
+ it("interpolates a compound builder expression verbatim in the default branch", () => {
350
+ const expression: string = "toDateTime(t.created_at)";
351
+ const result: string = AggregateUtil.buildBucketTimestampExpression(
352
+ AggregationInterval.Hour,
353
+ expression,
354
+ );
355
+ expect(result).toBe(
356
+ `date_trunc('hour', toStartOfInterval(${expression}, INTERVAL 1 hour))`,
357
+ );
358
+ });
359
+ });
360
+
361
+ describe("AggregateUtil.buildBucketTimestampSelect", () => {
362
+ const COL: string = "createdAt";
363
+
364
+ it("emits a self-aliased min() for Total (whole-window bucket)", () => {
365
+ const result: string = AggregateUtil.buildBucketTimestampSelect(
366
+ AggregationInterval.Total,
367
+ COL,
368
+ );
369
+ expect(result).toBe(`min(${COL}) as ${COL}`);
370
+ });
371
+
372
+ it("aliases the bucket expression for a sub-hour interval", () => {
373
+ const result: string = AggregateUtil.buildBucketTimestampSelect(
374
+ AggregationInterval.FiveMinutes,
375
+ COL,
376
+ );
377
+ expect(result).toBe(
378
+ `toStartOfInterval(${COL}, INTERVAL 5 MINUTE) as ${COL}`,
379
+ );
380
+ });
381
+
382
+ it("aliases the date_trunc expression for a calendar interval", () => {
383
+ const result: string = AggregateUtil.buildBucketTimestampSelect(
384
+ AggregationInterval.Minute,
385
+ COL,
386
+ );
387
+ expect(result).toBe(
388
+ `date_trunc('minute', toStartOfInterval(${COL}, INTERVAL 1 minute)) as ${COL}`,
389
+ );
390
+ });
391
+
392
+ it("delegates non-Total intervals to buildBucketTimestampExpression plus an alias", () => {
393
+ /*
394
+ * The select fragment for any non-Total interval must be exactly the
395
+ * bucket expression suffixed with `as <col>`; anything else would mean the
396
+ * two helpers had drifted apart.
397
+ */
398
+ const nonTotalIntervals: Array<AggregationInterval> = Object.values(
399
+ AggregationInterval,
400
+ ).filter((interval: AggregationInterval) => {
401
+ return interval !== AggregationInterval.Total;
402
+ });
403
+
404
+ for (const interval of nonTotalIntervals) {
405
+ const expression: string = AggregateUtil.buildBucketTimestampExpression(
406
+ interval,
407
+ COL,
408
+ );
409
+ const select: string = AggregateUtil.buildBucketTimestampSelect(
410
+ interval,
411
+ COL,
412
+ );
413
+ expect(select).toBe(`${expression} as ${COL}`);
414
+ }
415
+ });
416
+ });