@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,215 @@
1
+ import NetworkDeviceLinkRuleScope, {
2
+ NetworkDeviceLinkRuleScopeUtil,
3
+ } from "../../../Types/NetworkDevice/NetworkDeviceLinkRuleScope";
4
+
5
+ /*
6
+ * `scope` was added to a table that already had rules in it, so every rule
7
+ * written before the column existed holds NULL — and each of those rules is
8
+ * currently drawing a topology somebody has already looked at and trusted.
9
+ * NULL therefore has to read as Project, because Project is exactly what
10
+ * those rules have always meant: one parent across whatever device set the
11
+ * query handed the resolver. Read NULL as Site instead and every legacy rule
12
+ * quietly starts asking a different question, re-pointing cables on maps
13
+ * nobody re-opened. That is why the default lives in `parse` rather than in a
14
+ * `=== "Site"` comparison scattered over the call sites: one place to be
15
+ * right, and it is pinned here.
16
+ *
17
+ * The mirror of the same worry is the unrecognised value. The column is free
18
+ * text (the NetworkDeviceMonitoringMethod precedent), so a typo, an older
19
+ * client, or a future scope name that this build has never heard of can all
20
+ * land in it. Every one of them has to fall back to the behaviour that was
21
+ * already on screen rather than to the new one.
22
+ */
23
+ describe("NetworkDeviceLinkRuleScope enum", () => {
24
+ /*
25
+ * These strings are persisted values, not display labels. Renaming one is
26
+ * a silent data migration: every row already holding the old spelling stops
27
+ * being recognised and — by the fallback above — quietly reverts to
28
+ * Project, with no error anywhere to say so. Change these only alongside a
29
+ * migration that rewrites the column.
30
+ */
31
+ test("Project is persisted as the string Project", () => {
32
+ expect(NetworkDeviceLinkRuleScope.Project).toBe("Project");
33
+ });
34
+
35
+ test("Site is persisted as the string Site", () => {
36
+ expect(NetworkDeviceLinkRuleScope.Site).toBe("Site");
37
+ });
38
+
39
+ test("has exactly the two known scopes", () => {
40
+ expect(Object.values(NetworkDeviceLinkRuleScope).sort()).toEqual([
41
+ "Project",
42
+ "Site",
43
+ ]);
44
+ });
45
+ });
46
+
47
+ /*
48
+ * One table, two consumers. `parse` and `isSiteScoped` are asserted against
49
+ * the same rows further down so the pair cannot drift apart: a caller that
50
+ * branches on `isSiteScoped` and a caller that switches on `parse` must never
51
+ * disagree about the same stored string.
52
+ */
53
+ const PROJECT_INPUTS: Array<string | null | undefined> = [
54
+ // The pre-column rows, and the shapes an empty form field arrives as.
55
+ undefined,
56
+ null,
57
+ "",
58
+ " ",
59
+ // The value written by anything that does set the column explicitly.
60
+ "Project",
61
+ "project",
62
+ "PROJECT",
63
+ " Project ",
64
+ /*
65
+ * Near-misses that must NOT be read as site scope. "Sites" and
66
+ * "site-scoped" are the plausible typo and the plausible rename; matching
67
+ * them loosely would turn a mistyped rule into one that silently redraws.
68
+ */
69
+ "Sites",
70
+ "site-scoped",
71
+ "anything",
72
+ // Falsy-looking text is still just unrecognised text, not a flag.
73
+ "0",
74
+ "false",
75
+ ];
76
+
77
+ const SITE_INPUTS: Array<string> = [
78
+ "Site",
79
+ "site",
80
+ "SITE",
81
+ " site ",
82
+ " SiTe ",
83
+ ];
84
+
85
+ interface ScopeCase {
86
+ value: string | null | undefined;
87
+ expected: NetworkDeviceLinkRuleScope;
88
+ }
89
+
90
+ const ALL_CASES: Array<ScopeCase> = [
91
+ ...PROJECT_INPUTS.map((value: string | null | undefined): ScopeCase => {
92
+ return { value: value, expected: NetworkDeviceLinkRuleScope.Project };
93
+ }),
94
+ ...SITE_INPUTS.map((value: string): ScopeCase => {
95
+ return { value: value, expected: NetworkDeviceLinkRuleScope.Site };
96
+ }),
97
+ ];
98
+
99
+ describe("NetworkDeviceLinkRuleScopeUtil.parse", () => {
100
+ test.each(PROJECT_INPUTS)(
101
+ "reads %p as Project",
102
+ (value: string | null | undefined) => {
103
+ expect(NetworkDeviceLinkRuleScopeUtil.parse(value)).toBe(
104
+ NetworkDeviceLinkRuleScope.Project,
105
+ );
106
+ },
107
+ );
108
+
109
+ test.each(SITE_INPUTS)(
110
+ "reads %p as Site, case- and whitespace-insensitively",
111
+ (value: string) => {
112
+ expect(NetworkDeviceLinkRuleScopeUtil.parse(value)).toBe(
113
+ NetworkDeviceLinkRuleScope.Site,
114
+ );
115
+ },
116
+ );
117
+
118
+ /*
119
+ * Only an exact (trimmed, lowercased) "site" opts in. Substring matching
120
+ * would make "not site" or "site (deprecated)" flip the rule's meaning,
121
+ * which is the one direction of mistake this type refuses to make.
122
+ */
123
+ test("does not treat a string merely containing 'site' as site-scoped", () => {
124
+ expect(NetworkDeviceLinkRuleScopeUtil.parse("per site")).toBe(
125
+ NetworkDeviceLinkRuleScope.Project,
126
+ );
127
+ expect(NetworkDeviceLinkRuleScopeUtil.parse("not site")).toBe(
128
+ NetworkDeviceLinkRuleScope.Project,
129
+ );
130
+ });
131
+
132
+ /*
133
+ * The return value is always one of the two enum members — never the raw
134
+ * column text passed straight back. Callers switch on it, and a passthrough
135
+ * would send an unrecognised spelling into a branch that does not exist.
136
+ */
137
+ test("returns an enum member for every case in the table, never the raw input", () => {
138
+ for (const testCase of ALL_CASES) {
139
+ const parsed: NetworkDeviceLinkRuleScope =
140
+ NetworkDeviceLinkRuleScopeUtil.parse(testCase.value);
141
+
142
+ expect(Object.values(NetworkDeviceLinkRuleScope)).toContain(parsed);
143
+ }
144
+ });
145
+
146
+ /*
147
+ * The parser sits in the middle of rendering a topology map: throwing here
148
+ * would take out the whole map over one bad cell, when the safe answer
149
+ * (Project, what the rule drew yesterday) is right there. So nothing in the
150
+ * declared signature may throw — and neither may the falsy non-string
151
+ * shapes a loosely typed caller or a hand-rolled JSON body can smuggle past
152
+ * TypeScript, which the `|| ""` guard absorbs.
153
+ */
154
+ test("never throws for any value in or near its declared signature", () => {
155
+ const inputs: Array<string | null | undefined> = [
156
+ ...ALL_CASES.map((testCase: ScopeCase): string | null | undefined => {
157
+ return testCase.value;
158
+ }),
159
+ "\tSITE\n",
160
+ "\n project \t",
161
+ "Site\u0000",
162
+ "🙂",
163
+ ];
164
+
165
+ for (const input of inputs) {
166
+ expect((): NetworkDeviceLinkRuleScope => {
167
+ return NetworkDeviceLinkRuleScopeUtil.parse(input);
168
+ }).not.toThrow();
169
+ }
170
+
171
+ /*
172
+ * Not strings at all. 0/false/NaN are what a JSON body or a permissive
173
+ * ORM can hand over in place of "no scope set", and they have to land on
174
+ * the same safe default rather than blow up.
175
+ */
176
+ const nonStrings: Array<unknown> = [0, false, NaN];
177
+
178
+ for (const input of nonStrings) {
179
+ expect(
180
+ NetworkDeviceLinkRuleScopeUtil.parse(input as unknown as string),
181
+ ).toBe(NetworkDeviceLinkRuleScope.Project);
182
+ }
183
+ });
184
+ });
185
+
186
+ describe("NetworkDeviceLinkRuleScopeUtil.isSiteScoped", () => {
187
+ test.each(SITE_INPUTS)("is true for %p", (value: string) => {
188
+ expect(NetworkDeviceLinkRuleScopeUtil.isSiteScoped(value)).toBe(true);
189
+ });
190
+
191
+ test.each(PROJECT_INPUTS)(
192
+ "is false for %p",
193
+ (value: string | null | undefined) => {
194
+ expect(NetworkDeviceLinkRuleScopeUtil.isSiteScoped(value)).toBe(false);
195
+ },
196
+ );
197
+
198
+ /*
199
+ * The two entry points are asserted against the same table in the same
200
+ * loop, so neither can be extended (a new alias, a new scope) without the
201
+ * other. `NetworkDeviceLinkRuleUtil` branches on `isSiteScoped` while the
202
+ * dashboard's rule list renders off it too — if they ever disagreed, a rule
203
+ * would be labelled one way and resolved the other.
204
+ */
205
+ test("agrees with parse on every case in the table", () => {
206
+ for (const testCase of ALL_CASES) {
207
+ expect(NetworkDeviceLinkRuleScopeUtil.parse(testCase.value)).toBe(
208
+ testCase.expected,
209
+ );
210
+ expect(NetworkDeviceLinkRuleScopeUtil.isSiteScoped(testCase.value)).toBe(
211
+ testCase.expected === NetworkDeviceLinkRuleScope.Site,
212
+ );
213
+ }
214
+ });
215
+ });
@@ -0,0 +1,255 @@
1
+ import {
2
+ SERVICE_LANGUAGE_DISPLAY_NAMES,
3
+ ServiceLanguage,
4
+ detectServiceLanguage,
5
+ } from "../../../Types/Service/ServiceLanguage";
6
+ import TechStack from "../../../Types/Service/TechStack";
7
+
8
+ /*
9
+ * Which runtime a service is written in, decided from three sources of
10
+ * evidence of decreasing trustworthiness.
11
+ *
12
+ * This used to only pick which charts to draw on the service overview, where
13
+ * a wrong answer is a chart with no data in it. It now also picks which
14
+ * monitors OneUptime recommends, where a wrong answer is a monitor that
15
+ * queries a metric the service never emits and therefore never fires — a
16
+ * silent gap that reads as coverage. Every case below is about the difference
17
+ * between "we know" and "we are guessing".
18
+ */
19
+
20
+ const ALL_LANGUAGES: Array<ServiceLanguage> = Object.keys(
21
+ SERVICE_LANGUAGE_DISPLAY_NAMES,
22
+ ) as Array<ServiceLanguage>;
23
+
24
+ describe("detectServiceLanguage", () => {
25
+ describe("precedence between the three sources", () => {
26
+ /*
27
+ * The order is not arbitrary. `telemetry.sdk.language` is stamped by the
28
+ * SDK inside the process, so it describes what the process actually runs
29
+ * on. `process.runtime.name` is the same information one hop later.
30
+ * The tech stack is a human's answer typed into a form, which can be
31
+ * months out of date. Each test below sets up a deliberate disagreement
32
+ * so the winner is unambiguous.
33
+ */
34
+ it("prefers the SDK language over the runtime name", () => {
35
+ expect(
36
+ detectServiceLanguage({
37
+ telemetrySdkLanguage: "go",
38
+ runtimeName: "OpenJDK Runtime Environment",
39
+ }),
40
+ ).toBe("go");
41
+ });
42
+
43
+ it("prefers the SDK language over the tech stack", () => {
44
+ expect(
45
+ detectServiceLanguage({
46
+ telemetrySdkLanguage: "python",
47
+ techStack: [TechStack.Java],
48
+ }),
49
+ ).toBe("python");
50
+ });
51
+
52
+ it("prefers the runtime name over the tech stack", () => {
53
+ expect(
54
+ detectServiceLanguage({
55
+ runtimeName: "node",
56
+ techStack: [TechStack.Java],
57
+ }),
58
+ ).toBe("nodejs");
59
+ });
60
+
61
+ it("falls through to the tech stack when telemetry says nothing", () => {
62
+ expect(
63
+ detectServiceLanguage({
64
+ techStack: [TechStack.Rust],
65
+ }),
66
+ ).toBe("rust");
67
+ });
68
+ });
69
+
70
+ describe("the SDK language attribute", () => {
71
+ it.each(ALL_LANGUAGES)("recognises %s", (language: ServiceLanguage) => {
72
+ expect(detectServiceLanguage({ telemetrySdkLanguage: language })).toBe(
73
+ language,
74
+ );
75
+ });
76
+
77
+ it("is matched case-insensitively and ignores surrounding whitespace", () => {
78
+ expect(
79
+ detectServiceLanguage({ telemetrySdkLanguage: " DotNet " }),
80
+ ).toBe("dotnet");
81
+ });
82
+
83
+ /*
84
+ * The important negative case. An unrecognised value must NOT be returned
85
+ * verbatim — it would be a string that looks like a `ServiceLanguage` to
86
+ * every consumer and matches no template set, so the recommendations page
87
+ * would show nothing at all rather than the language-agnostic set.
88
+ */
89
+ it("does not pass an unrecognised SDK language through", () => {
90
+ expect(
91
+ detectServiceLanguage({ telemetrySdkLanguage: "cobol" }),
92
+ ).toBeNull();
93
+ });
94
+
95
+ it("falls through to the other sources when the SDK language is unknown", () => {
96
+ expect(
97
+ detectServiceLanguage({
98
+ telemetrySdkLanguage: "cobol",
99
+ techStack: [TechStack.Go],
100
+ }),
101
+ ).toBe("go");
102
+ });
103
+ });
104
+
105
+ describe("the runtime name markers", () => {
106
+ it.each([
107
+ ["OpenJDK 64-Bit Server VM", "java"],
108
+ ["GraalVM CE", "java"],
109
+ ["Java HotSpot(TM) 64-Bit Server VM", "java"],
110
+ [".NET 9.0.0", "dotnet"],
111
+ ["dotnet", "dotnet"],
112
+ ["node", "nodejs"],
113
+ ["Deno", "nodejs"],
114
+ ["bun", "nodejs"],
115
+ ["CPython", "python"],
116
+ ["PyPy", "python"],
117
+ ["BEAM", "erlang"],
118
+ ["Erlang/OTP 26", "erlang"],
119
+ ["ruby", "ruby"],
120
+ ["PHP 8.3", "php"],
121
+ ["rustc", "rust"],
122
+ ["swift", "swift"],
123
+ ["go", "go"],
124
+ ])(
125
+ "maps runtime name %s to %s",
126
+ (runtimeName: string, expected: string) => {
127
+ expect(detectServiceLanguage({ runtimeName: runtimeName })).toBe(
128
+ expected,
129
+ );
130
+ },
131
+ );
132
+
133
+ /*
134
+ * `go` is a two-letter substring, so it appears inside plenty of words —
135
+ * "GraalVM" does not contain it, but the ordering still matters and this
136
+ * pins it: the JVM markers are checked first, so a runtime string that
137
+ * contains both loses to the more specific one.
138
+ */
139
+ it("checks specific markers before the two-letter go marker", () => {
140
+ expect(
141
+ detectServiceLanguage({ runtimeName: "GraalVM for Go interop" }),
142
+ ).toBe("java");
143
+ });
144
+
145
+ it("returns null for a runtime name it does not recognise", () => {
146
+ expect(detectServiceLanguage({ runtimeName: "SomeVM 1.0" })).toBeNull();
147
+ });
148
+ });
149
+
150
+ describe("the tech stack fallback", () => {
151
+ it("maps Kotlin to java, because the runtime is what matters", () => {
152
+ expect(detectServiceLanguage({ techStack: [TechStack.Kotlin] })).toBe(
153
+ "java",
154
+ );
155
+ });
156
+
157
+ it("maps C# to dotnet", () => {
158
+ expect(detectServiceLanguage({ techStack: [TechStack.CSharp] })).toBe(
159
+ "dotnet",
160
+ );
161
+ });
162
+
163
+ it.each([TechStack.TypeScript, TechStack.JavaScript, TechStack.NodeJS])(
164
+ "maps %s to nodejs",
165
+ (techStack: TechStack) => {
166
+ expect(detectServiceLanguage({ techStack: [techStack] })).toBe(
167
+ "nodejs",
168
+ );
169
+ },
170
+ );
171
+
172
+ it("maps React to webjs rather than to nodejs", () => {
173
+ expect(detectServiceLanguage({ techStack: [TechStack.React] })).toBe(
174
+ "webjs",
175
+ );
176
+ });
177
+
178
+ it("takes the first entry that maps to a runtime", () => {
179
+ expect(
180
+ detectServiceLanguage({
181
+ techStack: [TechStack.Shell, TechStack.Markdown, TechStack.Go],
182
+ }),
183
+ ).toBe("go");
184
+ });
185
+
186
+ it.each([TechStack.Shell, TechStack.Markdown, TechStack.Other])(
187
+ "does not invent a runtime for %s",
188
+ (techStack: TechStack) => {
189
+ expect(detectServiceLanguage({ techStack: [techStack] })).toBeNull();
190
+ },
191
+ );
192
+ });
193
+
194
+ describe("when nothing identifies the runtime", () => {
195
+ /*
196
+ * Null, never a default. A default would hand every unidentified service
197
+ * one language's recommendations — monitors on metrics it does not emit,
198
+ * presented as if OneUptime had established what it runs on.
199
+ */
200
+ it("returns null for no input at all", () => {
201
+ expect(detectServiceLanguage({})).toBeNull();
202
+ });
203
+
204
+ it("returns null for empty strings and an empty tech stack", () => {
205
+ expect(
206
+ detectServiceLanguage({
207
+ telemetrySdkLanguage: "",
208
+ runtimeName: "",
209
+ techStack: [],
210
+ }),
211
+ ).toBeNull();
212
+ });
213
+
214
+ it("returns null for whitespace-only telemetry values", () => {
215
+ expect(
216
+ detectServiceLanguage({
217
+ telemetrySdkLanguage: " ",
218
+ runtimeName: " ",
219
+ }),
220
+ ).toBeNull();
221
+ });
222
+
223
+ it("returns null for explicitly undefined fields", () => {
224
+ expect(
225
+ detectServiceLanguage({
226
+ telemetrySdkLanguage: undefined,
227
+ runtimeName: undefined,
228
+ techStack: undefined,
229
+ }),
230
+ ).toBeNull();
231
+ });
232
+ });
233
+ });
234
+
235
+ describe("SERVICE_LANGUAGE_DISPLAY_NAMES", () => {
236
+ it("names every language, non-blank", () => {
237
+ expect(ALL_LANGUAGES.length).toBeGreaterThan(0);
238
+
239
+ for (const language of ALL_LANGUAGES) {
240
+ expect(
241
+ SERVICE_LANGUAGE_DISPLAY_NAMES[language].trim().length,
242
+ ).toBeGreaterThan(0);
243
+ }
244
+ });
245
+
246
+ it("gives each language a distinct display name", () => {
247
+ const names: Array<string> = ALL_LANGUAGES.map(
248
+ (language: ServiceLanguage) => {
249
+ return SERVICE_LANGUAGE_DISPLAY_NAMES[language];
250
+ },
251
+ );
252
+
253
+ expect(new Set<string>(names).size).toBe(names.length);
254
+ });
255
+ });
@@ -0,0 +1,211 @@
1
+ import Text from "../../Types/Text";
2
+ import { describe, expect, it } from "@jest/globals";
3
+
4
+ /*
5
+ * GHSA-5cr8-vph4-3hrf, CWE-330.
6
+ *
7
+ * Text.generateRandomNumber is what mints notification-channel verification
8
+ * codes. It used to draw from the literal string "12134567890" using
9
+ * Math.random, which is wrong twice over: the alphabet has "1" in it twice so
10
+ * the digits are not equally likely, and Math.random is a non-cryptographic
11
+ * PRNG whose state is recoverable from its own output.
12
+ *
13
+ * Neither property can be observed by looking at one value, which is why they
14
+ * survived. The tests below observe them the only ways available: by counting
15
+ * a large sample for bias, and by watching which source the generator actually
16
+ * pulls from.
17
+ */
18
+ describe("Text random generation", () => {
19
+ describe("generateRandomNumber", () => {
20
+ it("emits only digits, at the requested length", () => {
21
+ for (let length: number = 1; length <= 12; length++) {
22
+ const value: string = Text.generateRandomNumber(length);
23
+
24
+ expect(value).toHaveLength(length);
25
+ expect(value).toMatch(/^[0-9]+$/);
26
+ }
27
+ });
28
+
29
+ it("defaults to ten characters", () => {
30
+ expect(Text.generateRandomNumber()).toHaveLength(10);
31
+ });
32
+
33
+ /*
34
+ * The direct regression. With the old alphabet the digit "1" appeared
35
+ * twice in an eleven-character string, so it came up 2/11 of the time
36
+ * against 1/11 for every other digit — and "8" appeared once, like the
37
+ * rest, only because the typo happened to leave it in.
38
+ *
39
+ * 60,000 digits puts the expected count per digit at 6,000 with a
40
+ * standard deviation of about 73. The old generator produced ~10,909 ones
41
+ * and ~5,454 of everything else, so the bound below is enormously loose
42
+ * for a fair generator and enormously tight for the broken one.
43
+ */
44
+ it("draws every digit with equal probability", () => {
45
+ const sampleSize: number = 10000;
46
+ const digitsPerSample: number = 6;
47
+ const counts: Record<string, number> = {};
48
+
49
+ for (let i: number = 0; i < sampleSize; i++) {
50
+ for (const digit of Text.generateRandomNumber(digitsPerSample)) {
51
+ counts[digit] = (counts[digit] || 0) + 1;
52
+ }
53
+ }
54
+
55
+ const totalDigits: number = sampleSize * digitsPerSample;
56
+ const expectedPerDigit: number = totalDigits / 10;
57
+
58
+ /*
59
+ * Every digit must actually appear — "8" was reachable before, but a
60
+ * future typo in the alphabet would show up here.
61
+ */
62
+ expect(Object.keys(counts).sort()).toEqual([
63
+ "0",
64
+ "1",
65
+ "2",
66
+ "3",
67
+ "4",
68
+ "5",
69
+ "6",
70
+ "7",
71
+ "8",
72
+ "9",
73
+ ]);
74
+
75
+ for (const digit of Object.keys(counts)) {
76
+ const count: number = counts[digit] as number;
77
+
78
+ /*
79
+ * Six sigma either way: a fair generator fails this about once in
80
+ * 500 million runs, the old one fails it every time.
81
+ */
82
+ expect(count).toBeGreaterThan(expectedPerDigit * 0.9);
83
+ expect(count).toBeLessThan(expectedPerDigit * 1.1);
84
+ }
85
+ });
86
+
87
+ /*
88
+ * Leading zeros are part of the code space. Dropping them — by going
89
+ * through a number, say — would quietly remove a tenth of it.
90
+ */
91
+ it("can produce codes with leading zeros", () => {
92
+ let sawLeadingZero: boolean = false;
93
+
94
+ for (let i: number = 0; i < 500; i++) {
95
+ if (Text.generateRandomNumber(6).startsWith("0")) {
96
+ sawLeadingZero = true;
97
+ break;
98
+ }
99
+ }
100
+
101
+ expect(sawLeadingZero).toBe(true);
102
+ });
103
+
104
+ /*
105
+ * The other half of CWE-330. Math.random is seeded per process and its
106
+ * internal state can be recovered from a handful of outputs, after which
107
+ * every future value is known exactly — no guessing required. Asserting
108
+ * on the SOURCE is the only way to pin this: any specific output is a
109
+ * legal output of either generator.
110
+ */
111
+ it("does not fall back to Math.random when a CSPRNG is available", () => {
112
+ const mathRandomSpy: jest.SpyInstance = jest.spyOn(Math, "random");
113
+
114
+ try {
115
+ for (let i: number = 0; i < 100; i++) {
116
+ Text.generateRandomNumber(6);
117
+ }
118
+
119
+ expect(mathRandomSpy).not.toHaveBeenCalled();
120
+ } finally {
121
+ mathRandomSpy.mockRestore();
122
+ }
123
+ });
124
+
125
+ it("takes its bytes from crypto.getRandomValues", () => {
126
+ const getRandomValuesSpy: jest.SpyInstance = jest.spyOn(
127
+ globalThis.crypto,
128
+ "getRandomValues",
129
+ );
130
+
131
+ try {
132
+ Text.generateRandomNumber(6);
133
+
134
+ expect(getRandomValuesSpy).toHaveBeenCalled();
135
+ } finally {
136
+ getRandomValuesSpy.mockRestore();
137
+ }
138
+ });
139
+
140
+ it("produces a different value practically every time", () => {
141
+ const seen: Set<string> = new Set<string>();
142
+
143
+ for (let i: number = 0; i < 1000; i++) {
144
+ seen.add(Text.generateRandomNumber(10));
145
+ }
146
+
147
+ /*
148
+ * Ten digits, a thousand draws: collisions are vanishingly unlikely,
149
+ * and a stuck generator would collapse this to 1.
150
+ */
151
+ expect(seen.size).toBe(1000);
152
+ });
153
+ });
154
+
155
+ describe("generateRandomText", () => {
156
+ it("emits only letters, at the requested length", () => {
157
+ for (let length: number = 1; length <= 40; length += 7) {
158
+ const value: string = Text.generateRandomText(length);
159
+
160
+ expect(value).toHaveLength(length);
161
+ expect(value).toMatch(/^[A-Za-z]+$/);
162
+ }
163
+ });
164
+
165
+ it("defaults to ten characters", () => {
166
+ expect(Text.generateRandomText()).toHaveLength(10);
167
+ });
168
+
169
+ it("does not fall back to Math.random when a CSPRNG is available", () => {
170
+ const mathRandomSpy: jest.SpyInstance = jest.spyOn(Math, "random");
171
+
172
+ try {
173
+ for (let i: number = 0; i < 100; i++) {
174
+ Text.generateRandomText(20);
175
+ }
176
+
177
+ expect(mathRandomSpy).not.toHaveBeenCalled();
178
+ } finally {
179
+ mathRandomSpy.mockRestore();
180
+ }
181
+ });
182
+
183
+ /*
184
+ * Both alphabets have 52 characters, which does NOT divide 256 — so
185
+ * `byte % 52` would be biased towards the first 48 letters. The rejection
186
+ * sampling is what removes that, and this is the test that would notice
187
+ * if somebody "simplified" it away.
188
+ */
189
+ it("draws every letter with roughly equal probability", () => {
190
+ const counts: Record<string, number> = {};
191
+ const totalCharacters: number = 52 * 2000;
192
+
193
+ for (let i: number = 0; i < 2000; i++) {
194
+ for (const character of Text.generateRandomText(52)) {
195
+ counts[character] = (counts[character] || 0) + 1;
196
+ }
197
+ }
198
+
199
+ expect(Object.keys(counts)).toHaveLength(52);
200
+
201
+ const expectedPerCharacter: number = totalCharacters / 52;
202
+
203
+ for (const character of Object.keys(counts)) {
204
+ const count: number = counts[character] as number;
205
+
206
+ expect(count).toBeGreaterThan(expectedPerCharacter * 0.85);
207
+ expect(count).toBeLessThan(expectedPerCharacter * 1.15);
208
+ }
209
+ });
210
+ });
211
+ });