@oneuptime/common 12.0.15 → 12.0.17

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 (718) hide show
  1. package/Models/AnalyticsModels/Index.ts +10 -0
  2. package/Models/AnalyticsModels/LogCountBaseline.ts +174 -0
  3. package/Models/AnalyticsModels/SecurityEvent.ts +794 -0
  4. package/Models/AnalyticsModels/Span.ts +29 -1
  5. package/Models/AnalyticsModels/SpanCountBaseline.ts +198 -0
  6. package/Models/DatabaseModels/Alert.ts +42 -0
  7. package/Models/DatabaseModels/AlertMeasurement.ts +1114 -0
  8. package/Models/DatabaseModels/AlertMeasurementValue.ts +501 -0
  9. package/Models/DatabaseModels/AlertStateTimeline.ts +10 -2
  10. package/Models/DatabaseModels/BillingPaymentMethod.ts +8 -10
  11. package/Models/DatabaseModels/DetectionRule.ts +568 -0
  12. package/Models/DatabaseModels/GoogleSecOpsConnection.ts +382 -0
  13. package/Models/DatabaseModels/Incident.ts +42 -0
  14. package/Models/DatabaseModels/IncidentMeasurement.ts +1114 -0
  15. package/Models/DatabaseModels/IncidentMeasurementValue.ts +501 -0
  16. package/Models/DatabaseModels/IncidentStateTimeline.ts +10 -2
  17. package/Models/DatabaseModels/IncomingCallPolicyLabelRule.ts +36 -0
  18. package/Models/DatabaseModels/IncomingCallPolicyOwnerRule.ts +42 -0
  19. package/Models/DatabaseModels/Index.ts +20 -0
  20. package/Models/DatabaseModels/Label.ts +11 -0
  21. package/Models/DatabaseModels/LlmCostBudget.ts +655 -0
  22. package/Models/DatabaseModels/LlmModelPrice.ts +481 -0
  23. package/Models/DatabaseModels/LogSavedView.ts +87 -0
  24. package/Models/DatabaseModels/MarketingConversion.ts +210 -8
  25. package/Models/DatabaseModels/MetricSavedView.ts +59 -0
  26. package/Models/DatabaseModels/OnCallDutyPolicyLabelRule.ts +36 -0
  27. package/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.ts +42 -0
  28. package/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.ts +36 -0
  29. package/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.ts +42 -0
  30. package/Models/DatabaseModels/Probe.ts +21 -0
  31. package/Models/DatabaseModels/RunbookLabelRule.ts +36 -0
  32. package/Models/DatabaseModels/RunbookOwnerRule.ts +42 -0
  33. package/Models/DatabaseModels/ScheduledMaintenanceMeasurement.ts +1104 -0
  34. package/Models/DatabaseModels/ScheduledMaintenanceMeasurementValue.ts +491 -0
  35. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +10 -2
  36. package/Models/DatabaseModels/StatusPageLabelRule.ts +36 -0
  37. package/Models/DatabaseModels/StatusPageOwnerRule.ts +42 -0
  38. package/Models/DatabaseModels/TableView.ts +15 -0
  39. package/Models/DatabaseModels/Team.ts +13 -0
  40. package/Models/DatabaseModels/TeamMember.ts +8 -0
  41. package/Models/DatabaseModels/TraceSavedView.ts +52 -0
  42. package/Models/DatabaseModels/WorkflowLabelRule.ts +36 -0
  43. package/Models/DatabaseModels/WorkflowOwnerRule.ts +42 -0
  44. package/Server/API/TelemetryAPI.ts +252 -6
  45. package/Server/API/UserAPI.ts +88 -0
  46. package/Server/EnvironmentConfig.ts +36 -1
  47. package/Server/Infrastructure/Postgres/SchemaMigrations/1788000000000-AddDetectionRuleAndGoogleSecOpsConnection.ts +88 -0
  48. package/Server/Infrastructure/Postgres/SchemaMigrations/1788100000000-AddMeasurements.ts +457 -0
  49. package/Server/Infrastructure/Postgres/SchemaMigrations/1788200000000-AddLlmCostBudget.ts +97 -0
  50. package/Server/Infrastructure/Postgres/SchemaMigrations/1788300000000-AddLlmModelPrice.ts +45 -0
  51. package/Server/Infrastructure/Postgres/SchemaMigrations/1788400000000-AddMarketingConversionAttribution.ts +105 -0
  52. package/Server/Infrastructure/Postgres/SchemaMigrations/1788500000000-RemoveLlmCostBudgetAlertColumns.ts +77 -0
  53. package/Server/Infrastructure/Postgres/SchemaMigrations/1788600000000-AddDetectionRuleIncidentColumns.ts +39 -0
  54. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
  55. package/Server/Middleware/IdentityRateLimit.ts +672 -0
  56. package/Server/Services/AccessTokenService.ts +15 -2
  57. package/Server/Services/AlertMeasurementService.ts +302 -0
  58. package/Server/Services/AlertMeasurementValueService.ts +508 -0
  59. package/Server/Services/AlertService.ts +50 -0
  60. package/Server/Services/AlertStateTimelineService.ts +54 -0
  61. package/Server/Services/DetectionRuleService.ts +74 -0
  62. package/Server/Services/GoogleSecOpsConnectionService.ts +89 -0
  63. package/Server/Services/IncidentMeasurementService.ts +304 -0
  64. package/Server/Services/IncidentMeasurementValueService.ts +523 -0
  65. package/Server/Services/IncidentService.ts +51 -0
  66. package/Server/Services/IncidentStateTimelineService.ts +54 -0
  67. package/Server/Services/Index.ts +30 -0
  68. package/Server/Services/LlmCostBudgetService.ts +93 -0
  69. package/Server/Services/LlmModelPriceService.ts +202 -0
  70. package/Server/Services/LogAggregationService.ts +1106 -2
  71. package/Server/Services/LogCountBaselineService.ts +163 -0
  72. package/Server/Services/MutableMetricService.ts +30 -9
  73. package/Server/Services/ScheduledMaintenanceMeasurementService.ts +311 -0
  74. package/Server/Services/ScheduledMaintenanceMeasurementValueService.ts +546 -0
  75. package/Server/Services/ScheduledMaintenanceService.ts +53 -0
  76. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +188 -1
  77. package/Server/Services/SecurityEventService.ts +104 -0
  78. package/Server/Services/SpanCountBaselineService.ts +173 -0
  79. package/Server/Services/StatusPageService.ts +4 -3
  80. package/Server/Services/TelemetryUsageBillingService.ts +17 -2
  81. package/Server/Services/UserService.ts +284 -51
  82. package/Server/Services/UserTotpAuthService.ts +27 -86
  83. package/Server/Services/UserWebAuthnService.ts +26 -86
  84. package/Server/Types/Billing/MeteredPlan/AllMeteredPlans.ts +14 -0
  85. package/Server/Types/Database/Permissions/TenantPermission.ts +10 -0
  86. package/Server/Types/Database/QueryHelper.ts +1 -1
  87. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
  88. package/Server/Utils/AI/Toolbox/Index.ts +6 -0
  89. package/Server/Utils/AI/Toolbox/SecurityEventTools.ts +349 -0
  90. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +13 -4
  91. package/Server/Utils/Attribution.ts +130 -34
  92. package/Server/Utils/Marketing/ConversionUploadProvider.ts +98 -16
  93. package/Server/Utils/Marketing/Providers/GoogleAds.ts +70 -7
  94. package/Server/Utils/Marketing/Providers/LinkedIn.ts +54 -16
  95. package/Server/Utils/Marketing/Providers/Meta.ts +52 -18
  96. package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +37 -10
  97. package/Server/Utils/Marketing/Providers/Reddit.ts +45 -15
  98. package/Server/Utils/Measurement/MeasurementDefinitionValidator.ts +209 -0
  99. package/Server/Utils/Measurement/MeasurementMetricWriter.ts +189 -0
  100. package/Server/Utils/Monitor/Criteria/CountAnomaly.ts +182 -0
  101. package/Server/Utils/Monitor/Criteria/LogMonitorCriteria.ts +132 -0
  102. package/Server/Utils/Monitor/Criteria/SecurityEventsMonitorCriteria.ts +35 -0
  103. package/Server/Utils/Monitor/Criteria/TraceMonitorCriteria.ts +132 -0
  104. package/Server/Utils/Monitor/DataToProcess.ts +2 -0
  105. package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
  106. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +15 -0
  107. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +20 -0
  108. package/Server/Utils/Monitor/MonitorResource.ts +16 -0
  109. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +1 -0
  110. package/Server/Utils/Monitor/MonitorStepsReferenceExtractor.ts +1 -0
  111. package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +805 -0
  112. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.ts +262 -0
  113. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +212 -0
  114. package/Server/Utils/SecurityEvent/SecurityEventRow.ts +101 -0
  115. package/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.ts +635 -0
  116. package/Server/Utils/Telemetry/LlmCostBudgetEvaluator.ts +379 -0
  117. package/Server/Utils/Telemetry/LlmSpan.ts +83 -4
  118. package/Server/Utils/Telemetry/LogErrorPatternSql.ts +136 -0
  119. package/Server/Utils/UserPermission/UserPermission.ts +57 -1
  120. package/Tests/App/Dashboard/AlertsSideMenu.test.tsx +4 -0
  121. package/Tests/App/Dashboard/CreatePageEntryPointPermissions.test.tsx +306 -0
  122. package/Tests/App/Dashboard/DangerZone.test.tsx +11 -0
  123. package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +4 -0
  124. package/Tests/App/Dashboard/LogMonitorAttributeOperatorPreview.test.tsx +459 -0
  125. package/Tests/App/Dashboard/OverviewCustomFields.test.tsx +24 -0
  126. package/Tests/App/Dashboard/ScheduledMaintenanceSideMenu.test.tsx +6 -0
  127. package/Tests/App/Dashboard/SecurityEventsDetectionRulesPage.test.tsx +250 -0
  128. package/Tests/App/Dashboard/SecurityEventsMonitorStepForm.test.tsx +106 -0
  129. package/Tests/App/Dashboard/SecurityEventsMonitorsPage.test.tsx +185 -0
  130. package/Tests/App/Dashboard/SecurityEventsSetupGuide.test.tsx +200 -0
  131. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +323 -0
  132. package/Tests/Models/DatabaseModels/ProjectSharedResources.test.ts +386 -0
  133. package/Tests/Models/DetectionRuleCreateContract.test.ts +35 -0
  134. package/Tests/Server/API/LogErrorPatternAPI.test.ts +811 -0
  135. package/Tests/Server/API/UserAuthenticationAPI.test.ts +11 -0
  136. package/Tests/Server/API/UserProjectsAPI.test.ts +11 -2
  137. package/Tests/Server/API/UserTwoFactorAuthAdminAPI.test.ts +918 -0
  138. package/Tests/Server/Infrastructure/LocalCache.test.ts +149 -0
  139. package/Tests/Server/Services/AccessTokenProjectUserGrant.test.ts +249 -0
  140. package/Tests/Server/Services/AlertMeasurementService.test.ts +665 -0
  141. package/Tests/Server/Services/AlertMeasurementValueService.test.ts +389 -0
  142. package/Tests/Server/Services/DetectionRuleService.test.ts +254 -0
  143. package/Tests/Server/Services/IncidentMeasurementService.test.ts +394 -0
  144. package/Tests/Server/Services/IncidentMeasurementValueService.test.ts +816 -0
  145. package/Tests/Server/Services/LlmCostBudgetService.test.ts +104 -0
  146. package/Tests/Server/Services/LogAggregationAttributeOperators.test.ts +405 -0
  147. package/Tests/Server/Services/LogErrorPatternAggregation.test.ts +804 -0
  148. package/Tests/Server/Services/MutableMetricNameRouting.test.ts +83 -0
  149. package/Tests/Server/Services/ScheduledMaintenanceMeasurementService.test.ts +750 -0
  150. package/Tests/Server/Services/ScheduledMaintenanceMeasurementValueService.test.ts +478 -0
  151. package/Tests/Server/Services/UserAuthenticationService.test.ts +216 -4
  152. package/Tests/Server/Services/UserTwoFactorAuthAdmin.test.ts +1190 -0
  153. package/Tests/Server/Types/Database/Permissions/ScopedRoleSharedResourceAccess.test.ts +466 -0
  154. package/Tests/Server/Types/Database/QueryHelperOperators.test.ts +265 -0
  155. package/Tests/Server/Types/Database/QueryHelperTextAndStructuralOperators.test.ts +206 -0
  156. package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +6 -0
  157. package/Tests/Server/Utils/AnalyticsDatabase/FractionalAttributeThreshold.test.ts +224 -0
  158. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +172 -2
  159. package/Tests/Server/Utils/Attribution.test.ts +228 -1
  160. package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +153 -92
  161. package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +123 -6
  162. package/Tests/Server/Utils/Marketing/GoogleAds.test.ts +253 -1
  163. package/Tests/Server/Utils/Marketing/LinkedIn.test.ts +282 -0
  164. package/Tests/Server/Utils/Marketing/Meta.test.ts +304 -0
  165. package/Tests/Server/Utils/Marketing/MicrosoftAds.test.ts +263 -0
  166. package/Tests/Server/Utils/Marketing/Reddit.test.ts +259 -0
  167. package/Tests/Server/Utils/Measurement/MeasurementDefinitionValidator.test.ts +322 -0
  168. package/Tests/Server/Utils/Measurement/MeasurementMetricWriter.test.ts +373 -0
  169. package/Tests/Server/Utils/Monitor/Criteria/CountAnomaly.test.ts +221 -0
  170. package/Tests/Server/Utils/Monitor/Criteria/LogMonitorCriteria.test.ts +236 -0
  171. package/Tests/Server/Utils/Monitor/Criteria/SecurityEventsMonitorCriteria.test.ts +147 -0
  172. package/Tests/Server/Utils/Monitor/Criteria/TraceMonitorCriteria.test.ts +274 -0
  173. package/Tests/Server/Utils/Monitor/SecurityEventsMonitorDataExtractor.test.ts +93 -0
  174. package/Tests/Server/Utils/SecurityEvent/DetectionRuleEvaluator.test.ts +1098 -0
  175. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClient.test.ts +308 -0
  176. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +271 -0
  177. package/Tests/Server/Utils/SecurityEvent/SecurityEventRow.test.ts +272 -0
  178. package/Tests/Server/Utils/SecurityEvent/SigmaClickhouseCompiler.test.ts +511 -0
  179. package/Tests/Server/Utils/Telemetry/LlmCostBudgetEvaluator.test.ts +497 -0
  180. package/Tests/Server/Utils/Telemetry/LlmSpan.test.ts +380 -0
  181. package/Tests/Server/Utils/Telemetry/LogErrorPatternSql.test.ts +207 -0
  182. package/Tests/Server/Utils/UserPermission/ProjectUserGrant.test.ts +293 -0
  183. package/Tests/Types/Monitor/MonitorStepInfraMonitorUtils.test.ts +194 -0
  184. package/Tests/Types/Monitor/MonitorStepSecurityEventsMonitor.test.ts +201 -0
  185. package/Tests/Types/SecurityEvent/OcsfEventClass.test.ts +105 -0
  186. package/Tests/Types/SecurityEvent/OcsfSeverity.test.ts +111 -0
  187. package/Tests/Types/Telemetry/LlmCostCatalog.test.ts +516 -0
  188. package/Tests/UI/Components/ActiveFilterChipsOperatorValues.test.tsx +222 -0
  189. package/Tests/UI/Components/BulkActionPermissionGating.test.tsx +296 -0
  190. package/Tests/UI/Components/CardModelDetailPermissionGating.test.tsx +305 -0
  191. package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +23 -0
  192. package/Tests/UI/Components/DictionaryFilterOperatorDisplay.test.ts +239 -0
  193. package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +267 -0
  194. package/Tests/UI/Components/DuplicateModel.test.tsx +37 -0
  195. package/Tests/UI/Components/ModelCardPermissionGating.test.tsx +348 -0
  196. package/Tests/UI/Components/ModelDelete.test.tsx +25 -1
  197. package/Tests/UI/Components/ModelFormCreatePermission.test.tsx +342 -0
  198. package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +680 -0
  199. package/Tests/UI/Components/OrderedStatesListCreateGate.test.tsx +174 -0
  200. package/Tests/UI/Components/SavedViewsDropdownSearch.test.tsx +1127 -0
  201. package/Tests/UI/Components/SavedViewsFacetSection.test.tsx +958 -0
  202. package/Tests/UI/Components/SavedViewsList.test.ts +699 -0
  203. package/Tests/UI/Components/SavedViewsSidebarIntegration.test.tsx +640 -0
  204. package/Tests/UI/Components/SavedViewsSurfaceParity.test.tsx +679 -0
  205. package/Tests/UI/Components/TableViewLoadFailure.test.tsx +248 -0
  206. package/Tests/UI/Types/UseComponentOutsideClick.test.tsx +226 -0
  207. package/Tests/UI/Utils/PermissionGate.test.ts +467 -0
  208. package/Tests/Utils/Measurement/MeasurementEvaluator.test.ts +639 -0
  209. package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
  210. package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +285 -0
  211. package/Tests/Utils/NetworkDevice/DeviceHealthStateUtil.test.ts +433 -0
  212. package/Tests/Utils/SecurityEvent/GenericNormalizer.test.ts +204 -0
  213. package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.test.ts +252 -0
  214. package/Tests/Utils/SecurityEvent/NormalizerHelpers.test.ts +274 -0
  215. package/Tests/Utils/SecurityEvent/OcsfNormalizer.test.ts +208 -0
  216. package/Tests/Utils/SecurityEvent/SecurityEventNormalizer.test.ts +172 -0
  217. package/Tests/Utils/SecurityEvent/SigmaRuleParser.test.ts +471 -0
  218. package/Tests/Utils/SecurityEvent/UdmNormalizer.test.ts +361 -0
  219. package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +82 -0
  220. package/Tests/Utils/Telemetry/LogErrorPattern.test.ts +463 -0
  221. package/Types/AI/AIChatTypes.ts +1 -0
  222. package/Types/Alerts/AlertMeasurementAnchorType.ts +14 -0
  223. package/Types/Alerts/AlertStateRole.ts +11 -0
  224. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +16 -0
  225. package/Types/Dashboard/Chart/ChartType.ts +1 -0
  226. package/Types/Dashboard/DashboardComponentType.ts +2 -0
  227. package/Types/Dashboard/DashboardComponents/DashboardSecurityEventsFlowComponent.ts +18 -0
  228. package/Types/Dashboard/DashboardComponents/DashboardSecurityEventsListComponent.ts +16 -0
  229. package/Types/Incident/IncidentMeasurementAnchorType.ts +34 -0
  230. package/Types/Incident/IncidentStateRole.ts +14 -0
  231. package/Types/Marketing/Attribution.ts +75 -0
  232. package/Types/Marketing/MarketingConversion.ts +37 -7
  233. package/Types/Measurement/MeasurementAggregationType.ts +43 -0
  234. package/Types/Measurement/MeasurementAnchorKind.ts +23 -0
  235. package/Types/Measurement/MeasurementOccurrence.ts +14 -0
  236. package/Types/Measurement/MeasurementStatus.ts +34 -0
  237. package/Types/MeteredPlan/ProductType.ts +1 -0
  238. package/Types/Monitor/CriteriaFilter.ts +3 -0
  239. package/Types/Monitor/MonitorCriteriaInstance.ts +64 -0
  240. package/Types/Monitor/MonitorStep.ts +28 -0
  241. package/Types/Monitor/MonitorStepSecurityEventsMonitor.ts +100 -0
  242. package/Types/Monitor/MonitorType.ts +20 -0
  243. package/Types/Monitor/SecurityEventsMonitor/SecurityEventsMonitorResponse.ts +17 -0
  244. package/Types/Permission.ts +399 -2
  245. package/Types/ScheduledMaintenance/ScheduledMaintenanceMeasurementAnchorType.ts +20 -0
  246. package/Types/ScheduledMaintenance/ScheduledMaintenanceStateRole.ts +16 -0
  247. package/Types/SecurityEvent/DetectionFindingConstants.ts +24 -0
  248. package/Types/SecurityEvent/NormalizedSecurityEvent.ts +92 -0
  249. package/Types/SecurityEvent/OcsfEventClass.ts +205 -0
  250. package/Types/SecurityEvent/OcsfSeverity.ts +88 -0
  251. package/Types/SecurityEvent/SecurityEventFormat.ts +23 -0
  252. package/Types/SecurityEvent/SigmaRule.ts +70 -0
  253. package/Types/Telemetry/LlmConventions.ts +20 -1
  254. package/Types/Telemetry/LlmCostCatalog.ts +557 -0
  255. package/Types/Telemetry/ServiceType.ts +1 -0
  256. package/Types/Telemetry/TelemetryRetentionConfig.ts +5 -1
  257. package/Types/Telemetry/TelemetryType.ts +1 -0
  258. package/Types/TwoFactorAuthStatus.ts +42 -0
  259. package/Types/UserAuthenticationStatus.ts +18 -0
  260. package/UI/Components/ActionButton/ActionButtonSchema.ts +7 -0
  261. package/UI/Components/BulkUpdate/BulkArchiveActions.tsx +35 -2
  262. package/UI/Components/BulkUpdate/BulkLabelActions.tsx +34 -1
  263. package/UI/Components/BulkUpdate/BulkOwnerActions.tsx +45 -1
  264. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +3 -0
  265. package/UI/Components/Button/Button.tsx +37 -2
  266. package/UI/Components/Card/Card.tsx +6 -0
  267. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +24 -1
  268. package/UI/Components/Dictionary/DictionaryFilterOperator.ts +57 -0
  269. package/UI/Components/DuplicateModel/DuplicateModel.tsx +16 -0
  270. package/UI/Components/Forms/ModelForm.tsx +54 -2
  271. package/UI/Components/List/ListRow.tsx +6 -0
  272. package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +34 -7
  273. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +7 -40
  274. package/UI/Components/LogsViewer/components/SavedViewsDropdown.tsx +155 -3
  275. package/UI/Components/ModelDelete/ModelDelete.tsx +20 -0
  276. package/UI/Components/ModelDetail/CardModelDetail.tsx +36 -23
  277. package/UI/Components/ModelList/ModelList.tsx +21 -2
  278. package/UI/Components/ModelList/StaticModelList.tsx +11 -0
  279. package/UI/Components/ModelTable/BaseModelTable.tsx +168 -62
  280. package/UI/Components/ModelTable/ModelTable.tsx +16 -10
  281. package/UI/Components/ModelTable/TableView.tsx +36 -4
  282. package/UI/Components/MoreMenu/MoreMenuItem.tsx +36 -4
  283. package/UI/Components/OrderedStatesList/Item.tsx +6 -0
  284. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +81 -47
  285. package/UI/Components/ResetObjectID/ResetObjectID.tsx +16 -0
  286. package/UI/Components/SavedViews/SavedViewsFacetSection.tsx +242 -0
  287. package/UI/Components/SavedViews/SavedViewsList.ts +168 -0
  288. package/UI/Components/SavedViews/SavedViewsSearchInput.tsx +46 -0
  289. package/UI/Components/SavedViews/SavedViewsShowMoreButton.tsx +44 -0
  290. package/UI/Components/Table/TableRow.tsx +12 -0
  291. package/UI/Components/TelemetryViewer/components/SavedViewsDropdown.tsx +152 -2
  292. package/UI/Types/UseComponentOutsideClick.ts +47 -0
  293. package/UI/Utils/PermissionGate.ts +277 -0
  294. package/Utils/Dashboard/Components/DashboardSecurityEventsFlowComponent.ts +84 -0
  295. package/Utils/Dashboard/Components/DashboardSecurityEventsListComponent.ts +110 -0
  296. package/Utils/Dashboard/Components/Index.ts +14 -0
  297. package/Utils/Measurement/MeasurementEvaluator.ts +359 -0
  298. package/Utils/Monitor/MonitorSummarySnapshotUtil.ts +1 -0
  299. package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +93 -11
  300. package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +231 -0
  301. package/Utils/SecurityEvent/GenericNormalizer.ts +208 -0
  302. package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +206 -0
  303. package/Utils/SecurityEvent/NormalizerHelpers.ts +263 -0
  304. package/Utils/SecurityEvent/OcsfNormalizer.ts +194 -0
  305. package/Utils/SecurityEvent/SecurityEventNormalizer.ts +82 -0
  306. package/Utils/SecurityEvent/Sigma/SigmaRuleParser.ts +579 -0
  307. package/Utils/SecurityEvent/UdmNormalizer.ts +442 -0
  308. package/Utils/Telemetry/CrossSignalScope.ts +46 -9
  309. package/Utils/Telemetry/LogErrorPattern.ts +350 -0
  310. package/build/dist/Models/AnalyticsModels/Index.js +10 -0
  311. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  312. package/build/dist/Models/AnalyticsModels/LogCountBaseline.js +159 -0
  313. package/build/dist/Models/AnalyticsModels/LogCountBaseline.js.map +1 -0
  314. package/build/dist/Models/AnalyticsModels/SecurityEvent.js +596 -0
  315. package/build/dist/Models/AnalyticsModels/SecurityEvent.js.map +1 -0
  316. package/build/dist/Models/AnalyticsModels/Span.js +24 -1
  317. package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
  318. package/build/dist/Models/AnalyticsModels/SpanCountBaseline.js +181 -0
  319. package/build/dist/Models/AnalyticsModels/SpanCountBaseline.js.map +1 -0
  320. package/build/dist/Models/DatabaseModels/Alert.js +43 -0
  321. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  322. package/build/dist/Models/DatabaseModels/AlertMeasurement.js +1143 -0
  323. package/build/dist/Models/DatabaseModels/AlertMeasurement.js.map +1 -0
  324. package/build/dist/Models/DatabaseModels/AlertMeasurementValue.js +523 -0
  325. package/build/dist/Models/DatabaseModels/AlertMeasurementValue.js.map +1 -0
  326. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +9 -2
  327. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
  328. package/build/dist/Models/DatabaseModels/BillingPaymentMethod.js +10 -11
  329. package/build/dist/Models/DatabaseModels/BillingPaymentMethod.js.map +1 -1
  330. package/build/dist/Models/DatabaseModels/DetectionRule.js +598 -0
  331. package/build/dist/Models/DatabaseModels/DetectionRule.js.map +1 -0
  332. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js +410 -0
  333. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js.map +1 -0
  334. package/build/dist/Models/DatabaseModels/Incident.js +43 -0
  335. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  336. package/build/dist/Models/DatabaseModels/IncidentMeasurement.js +1143 -0
  337. package/build/dist/Models/DatabaseModels/IncidentMeasurement.js.map +1 -0
  338. package/build/dist/Models/DatabaseModels/IncidentMeasurementValue.js +523 -0
  339. package/build/dist/Models/DatabaseModels/IncidentMeasurementValue.js.map +1 -0
  340. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +9 -2
  341. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  342. package/build/dist/Models/DatabaseModels/IncomingCallPolicyLabelRule.js +36 -0
  343. package/build/dist/Models/DatabaseModels/IncomingCallPolicyLabelRule.js.map +1 -1
  344. package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerRule.js +42 -0
  345. package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerRule.js.map +1 -1
  346. package/build/dist/Models/DatabaseModels/Index.js +20 -0
  347. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  348. package/build/dist/Models/DatabaseModels/Label.js +11 -0
  349. package/build/dist/Models/DatabaseModels/Label.js.map +1 -1
  350. package/build/dist/Models/DatabaseModels/LlmCostBudget.js +681 -0
  351. package/build/dist/Models/DatabaseModels/LlmCostBudget.js.map +1 -0
  352. package/build/dist/Models/DatabaseModels/LlmModelPrice.js +503 -0
  353. package/build/dist/Models/DatabaseModels/LlmModelPrice.js.map +1 -0
  354. package/build/dist/Models/DatabaseModels/LogSavedView.js +87 -0
  355. package/build/dist/Models/DatabaseModels/LogSavedView.js.map +1 -1
  356. package/build/dist/Models/DatabaseModels/MarketingConversion.js +224 -8
  357. package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -1
  358. package/build/dist/Models/DatabaseModels/MetricSavedView.js +59 -0
  359. package/build/dist/Models/DatabaseModels/MetricSavedView.js.map +1 -1
  360. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyLabelRule.js +36 -0
  361. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyLabelRule.js.map +1 -1
  362. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.js +42 -0
  363. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.js.map +1 -1
  364. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.js +36 -0
  365. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.js.map +1 -1
  366. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.js +42 -0
  367. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.js.map +1 -1
  368. package/build/dist/Models/DatabaseModels/Probe.js +21 -0
  369. package/build/dist/Models/DatabaseModels/Probe.js.map +1 -1
  370. package/build/dist/Models/DatabaseModels/RunbookLabelRule.js +36 -0
  371. package/build/dist/Models/DatabaseModels/RunbookLabelRule.js.map +1 -1
  372. package/build/dist/Models/DatabaseModels/RunbookOwnerRule.js +42 -0
  373. package/build/dist/Models/DatabaseModels/RunbookOwnerRule.js.map +1 -1
  374. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceMeasurement.js +1133 -0
  375. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceMeasurement.js.map +1 -0
  376. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceMeasurementValue.js +515 -0
  377. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceMeasurementValue.js.map +1 -0
  378. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +9 -2
  379. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  380. package/build/dist/Models/DatabaseModels/StatusPageLabelRule.js +36 -0
  381. package/build/dist/Models/DatabaseModels/StatusPageLabelRule.js.map +1 -1
  382. package/build/dist/Models/DatabaseModels/StatusPageOwnerRule.js +42 -0
  383. package/build/dist/Models/DatabaseModels/StatusPageOwnerRule.js.map +1 -1
  384. package/build/dist/Models/DatabaseModels/TableView.js +15 -0
  385. package/build/dist/Models/DatabaseModels/TableView.js.map +1 -1
  386. package/build/dist/Models/DatabaseModels/Team.js +13 -0
  387. package/build/dist/Models/DatabaseModels/Team.js.map +1 -1
  388. package/build/dist/Models/DatabaseModels/TeamMember.js +8 -0
  389. package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
  390. package/build/dist/Models/DatabaseModels/TraceSavedView.js +52 -0
  391. package/build/dist/Models/DatabaseModels/TraceSavedView.js.map +1 -1
  392. package/build/dist/Models/DatabaseModels/WorkflowLabelRule.js +36 -0
  393. package/build/dist/Models/DatabaseModels/WorkflowLabelRule.js.map +1 -1
  394. package/build/dist/Models/DatabaseModels/WorkflowOwnerRule.js +42 -0
  395. package/build/dist/Models/DatabaseModels/WorkflowOwnerRule.js.map +1 -1
  396. package/build/dist/Server/API/TelemetryAPI.js +136 -0
  397. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  398. package/build/dist/Server/API/UserAPI.js +75 -2
  399. package/build/dist/Server/API/UserAPI.js.map +1 -1
  400. package/build/dist/Server/EnvironmentConfig.js +29 -1
  401. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  402. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788000000000-AddDetectionRuleAndGoogleSecOpsConnection.js +36 -0
  403. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788000000000-AddDetectionRuleAndGoogleSecOpsConnection.js.map +1 -0
  404. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788100000000-AddMeasurements.js +162 -0
  405. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788100000000-AddMeasurements.js.map +1 -0
  406. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788200000000-AddLlmCostBudget.js +40 -0
  407. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788200000000-AddLlmCostBudget.js.map +1 -0
  408. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788300000000-AddLlmModelPrice.js +22 -0
  409. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788300000000-AddLlmModelPrice.js.map +1 -0
  410. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788400000000-AddMarketingConversionAttribution.js +52 -0
  411. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788400000000-AddMarketingConversionAttribution.js.map +1 -0
  412. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788500000000-RemoveLlmCostBudgetAlertColumns.js +38 -0
  413. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788500000000-RemoveLlmCostBudgetAlertColumns.js.map +1 -0
  414. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788600000000-AddDetectionRuleIncidentColumns.js +24 -0
  415. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788600000000-AddDetectionRuleIncidentColumns.js.map +1 -0
  416. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
  417. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  418. package/build/dist/Server/Middleware/IdentityRateLimit.js +491 -0
  419. package/build/dist/Server/Middleware/IdentityRateLimit.js.map +1 -0
  420. package/build/dist/Server/Services/AccessTokenService.js +13 -2
  421. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  422. package/build/dist/Server/Services/AlertMeasurementService.js +250 -0
  423. package/build/dist/Server/Services/AlertMeasurementService.js.map +1 -0
  424. package/build/dist/Server/Services/AlertMeasurementValueService.js +400 -0
  425. package/build/dist/Server/Services/AlertMeasurementValueService.js.map +1 -0
  426. package/build/dist/Server/Services/AlertService.js +37 -0
  427. package/build/dist/Server/Services/AlertService.js.map +1 -1
  428. package/build/dist/Server/Services/AlertStateTimelineService.js +48 -0
  429. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  430. package/build/dist/Server/Services/DetectionRuleService.js +50 -0
  431. package/build/dist/Server/Services/DetectionRuleService.js.map +1 -0
  432. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +55 -0
  433. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +1 -0
  434. package/build/dist/Server/Services/IncidentMeasurementService.js +252 -0
  435. package/build/dist/Server/Services/IncidentMeasurementService.js.map +1 -0
  436. package/build/dist/Server/Services/IncidentMeasurementValueService.js +413 -0
  437. package/build/dist/Server/Services/IncidentMeasurementValueService.js.map +1 -0
  438. package/build/dist/Server/Services/IncidentService.js +41 -0
  439. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  440. package/build/dist/Server/Services/IncidentStateTimelineService.js +50 -0
  441. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  442. package/build/dist/Server/Services/Index.js +30 -0
  443. package/build/dist/Server/Services/Index.js.map +1 -1
  444. package/build/dist/Server/Services/LlmCostBudgetService.js +89 -0
  445. package/build/dist/Server/Services/LlmCostBudgetService.js.map +1 -0
  446. package/build/dist/Server/Services/LlmModelPriceService.js +163 -0
  447. package/build/dist/Server/Services/LlmModelPriceService.js.map +1 -0
  448. package/build/dist/Server/Services/LogAggregationService.js +709 -0
  449. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  450. package/build/dist/Server/Services/LogCountBaselineService.js +112 -0
  451. package/build/dist/Server/Services/LogCountBaselineService.js.map +1 -0
  452. package/build/dist/Server/Services/MutableMetricService.js +28 -9
  453. package/build/dist/Server/Services/MutableMetricService.js.map +1 -1
  454. package/build/dist/Server/Services/ScheduledMaintenanceMeasurementService.js +254 -0
  455. package/build/dist/Server/Services/ScheduledMaintenanceMeasurementService.js.map +1 -0
  456. package/build/dist/Server/Services/ScheduledMaintenanceMeasurementValueService.js +434 -0
  457. package/build/dist/Server/Services/ScheduledMaintenanceMeasurementValueService.js.map +1 -0
  458. package/build/dist/Server/Services/ScheduledMaintenanceService.js +37 -0
  459. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  460. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +134 -0
  461. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  462. package/build/dist/Server/Services/SecurityEventService.js +64 -0
  463. package/build/dist/Server/Services/SecurityEventService.js.map +1 -0
  464. package/build/dist/Server/Services/SpanCountBaselineService.js +122 -0
  465. package/build/dist/Server/Services/SpanCountBaselineService.js.map +1 -0
  466. package/build/dist/Server/Services/StatusPageService.js +4 -3
  467. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  468. package/build/dist/Server/Services/TelemetryUsageBillingService.js +15 -3
  469. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  470. package/build/dist/Server/Services/UserService.js +262 -42
  471. package/build/dist/Server/Services/UserService.js.map +1 -1
  472. package/build/dist/Server/Services/UserTotpAuthService.js +0 -73
  473. package/build/dist/Server/Services/UserTotpAuthService.js.map +1 -1
  474. package/build/dist/Server/Services/UserWebAuthnService.js +1 -73
  475. package/build/dist/Server/Services/UserWebAuthnService.js.map +1 -1
  476. package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js +13 -0
  477. package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js.map +1 -1
  478. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +10 -0
  479. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
  480. package/build/dist/Server/Types/Database/QueryHelper.js +1 -1
  481. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  482. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
  483. package/build/dist/Server/Utils/AI/Toolbox/Index.js +3 -0
  484. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  485. package/build/dist/Server/Utils/AI/Toolbox/SecurityEventTools.js +257 -0
  486. package/build/dist/Server/Utils/AI/Toolbox/SecurityEventTools.js.map +1 -0
  487. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +13 -4
  488. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  489. package/build/dist/Server/Utils/Attribution.js +77 -33
  490. package/build/dist/Server/Utils/Attribution.js.map +1 -1
  491. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +46 -9
  492. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -1
  493. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +52 -8
  494. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -1
  495. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +41 -17
  496. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -1
  497. package/build/dist/Server/Utils/Marketing/Providers/Meta.js +42 -18
  498. package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -1
  499. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +24 -11
  500. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -1
  501. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +34 -15
  502. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -1
  503. package/build/dist/Server/Utils/Measurement/MeasurementDefinitionValidator.js +109 -0
  504. package/build/dist/Server/Utils/Measurement/MeasurementDefinitionValidator.js.map +1 -0
  505. package/build/dist/Server/Utils/Measurement/MeasurementMetricWriter.js +131 -0
  506. package/build/dist/Server/Utils/Measurement/MeasurementMetricWriter.js.map +1 -0
  507. package/build/dist/Server/Utils/Monitor/Criteria/CountAnomaly.js +111 -0
  508. package/build/dist/Server/Utils/Monitor/Criteria/CountAnomaly.js.map +1 -0
  509. package/build/dist/Server/Utils/Monitor/Criteria/LogMonitorCriteria.js +84 -1
  510. package/build/dist/Server/Utils/Monitor/Criteria/LogMonitorCriteria.js.map +1 -1
  511. package/build/dist/Server/Utils/Monitor/Criteria/SecurityEventsMonitorCriteria.js +35 -0
  512. package/build/dist/Server/Utils/Monitor/Criteria/SecurityEventsMonitorCriteria.js.map +1 -0
  513. package/build/dist/Server/Utils/Monitor/Criteria/TraceMonitorCriteria.js +84 -1
  514. package/build/dist/Server/Utils/Monitor/Criteria/TraceMonitorCriteria.js.map +1 -1
  515. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +7 -0
  516. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
  517. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +12 -0
  518. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  519. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +9 -0
  520. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  521. package/build/dist/Server/Utils/Monitor/MonitorResource.js +10 -0
  522. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  523. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +6 -5
  524. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
  525. package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js +1 -0
  526. package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js.map +1 -1
  527. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +600 -0
  528. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js.map +1 -0
  529. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js +145 -0
  530. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +1 -0
  531. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +176 -0
  532. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +1 -0
  533. package/build/dist/Server/Utils/SecurityEvent/SecurityEventRow.js +69 -0
  534. package/build/dist/Server/Utils/SecurityEvent/SecurityEventRow.js.map +1 -0
  535. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js +493 -0
  536. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js.map +1 -0
  537. package/build/dist/Server/Utils/Telemetry/LlmCostBudgetEvaluator.js +317 -0
  538. package/build/dist/Server/Utils/Telemetry/LlmCostBudgetEvaluator.js.map +1 -0
  539. package/build/dist/Server/Utils/Telemetry/LlmSpan.js +56 -4
  540. package/build/dist/Server/Utils/Telemetry/LlmSpan.js.map +1 -1
  541. package/build/dist/Server/Utils/Telemetry/LogErrorPatternSql.js +112 -0
  542. package/build/dist/Server/Utils/Telemetry/LogErrorPatternSql.js.map +1 -0
  543. package/build/dist/Server/Utils/UserPermission/UserPermission.js +46 -1
  544. package/build/dist/Server/Utils/UserPermission/UserPermission.js.map +1 -1
  545. package/build/dist/Types/AI/AIChatTypes.js +1 -0
  546. package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
  547. package/build/dist/Types/Alerts/AlertMeasurementAnchorType.js +15 -0
  548. package/build/dist/Types/Alerts/AlertMeasurementAnchorType.js.map +1 -0
  549. package/build/dist/Types/Alerts/AlertStateRole.js +12 -0
  550. package/build/dist/Types/Alerts/AlertStateRole.js.map +1 -0
  551. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +16 -0
  552. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  553. package/build/dist/Types/Dashboard/Chart/ChartType.js +1 -0
  554. package/build/dist/Types/Dashboard/Chart/ChartType.js.map +1 -1
  555. package/build/dist/Types/Dashboard/DashboardComponentType.js +2 -0
  556. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  557. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSecurityEventsFlowComponent.js +2 -0
  558. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSecurityEventsFlowComponent.js.map +1 -0
  559. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSecurityEventsListComponent.js +2 -0
  560. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSecurityEventsListComponent.js.map +1 -0
  561. package/build/dist/Types/Incident/IncidentMeasurementAnchorType.js +29 -0
  562. package/build/dist/Types/Incident/IncidentMeasurementAnchorType.js.map +1 -0
  563. package/build/dist/Types/Incident/IncidentStateRole.js +15 -0
  564. package/build/dist/Types/Incident/IncidentStateRole.js.map +1 -0
  565. package/build/dist/Types/Marketing/Attribution.js +68 -0
  566. package/build/dist/Types/Marketing/Attribution.js.map +1 -0
  567. package/build/dist/Types/Marketing/MarketingConversion.js +36 -7
  568. package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -1
  569. package/build/dist/Types/Measurement/MeasurementAggregationType.js +40 -0
  570. package/build/dist/Types/Measurement/MeasurementAggregationType.js.map +1 -0
  571. package/build/dist/Types/Measurement/MeasurementAnchorKind.js +22 -0
  572. package/build/dist/Types/Measurement/MeasurementAnchorKind.js.map +1 -0
  573. package/build/dist/Types/Measurement/MeasurementOccurrence.js +15 -0
  574. package/build/dist/Types/Measurement/MeasurementOccurrence.js.map +1 -0
  575. package/build/dist/Types/Measurement/MeasurementStatus.js +32 -0
  576. package/build/dist/Types/Measurement/MeasurementStatus.js.map +1 -0
  577. package/build/dist/Types/MeteredPlan/ProductType.js +1 -0
  578. package/build/dist/Types/MeteredPlan/ProductType.js.map +1 -1
  579. package/build/dist/Types/Monitor/CriteriaFilter.js +2 -0
  580. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  581. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +59 -0
  582. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  583. package/build/dist/Types/Monitor/MonitorStep.js +17 -0
  584. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  585. package/build/dist/Types/Monitor/MonitorStepSecurityEventsMonitor.js +64 -0
  586. package/build/dist/Types/Monitor/MonitorStepSecurityEventsMonitor.js.map +1 -0
  587. package/build/dist/Types/Monitor/MonitorType.js +19 -0
  588. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  589. package/build/dist/Types/Monitor/SecurityEventsMonitor/SecurityEventsMonitorResponse.js +2 -0
  590. package/build/dist/Types/Monitor/SecurityEventsMonitor/SecurityEventsMonitorResponse.js.map +1 -0
  591. package/build/dist/Types/Permission.js +347 -2
  592. package/build/dist/Types/Permission.js.map +1 -1
  593. package/build/dist/Types/ScheduledMaintenance/ScheduledMaintenanceMeasurementAnchorType.js +19 -0
  594. package/build/dist/Types/ScheduledMaintenance/ScheduledMaintenanceMeasurementAnchorType.js.map +1 -0
  595. package/build/dist/Types/ScheduledMaintenance/ScheduledMaintenanceStateRole.js +17 -0
  596. package/build/dist/Types/ScheduledMaintenance/ScheduledMaintenanceStateRole.js.map +1 -0
  597. package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js +18 -0
  598. package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js.map +1 -0
  599. package/build/dist/Types/SecurityEvent/NormalizedSecurityEvent.js +2 -0
  600. package/build/dist/Types/SecurityEvent/NormalizedSecurityEvent.js.map +1 -0
  601. package/build/dist/Types/SecurityEvent/OcsfEventClass.js +181 -0
  602. package/build/dist/Types/SecurityEvent/OcsfEventClass.js.map +1 -0
  603. package/build/dist/Types/SecurityEvent/OcsfSeverity.js +81 -0
  604. package/build/dist/Types/SecurityEvent/OcsfSeverity.js.map +1 -0
  605. package/build/dist/Types/SecurityEvent/SecurityEventFormat.js +21 -0
  606. package/build/dist/Types/SecurityEvent/SecurityEventFormat.js.map +1 -0
  607. package/build/dist/Types/SecurityEvent/SigmaRule.js +16 -0
  608. package/build/dist/Types/SecurityEvent/SigmaRule.js.map +1 -0
  609. package/build/dist/Types/Telemetry/LlmConventions.js +19 -1
  610. package/build/dist/Types/Telemetry/LlmConventions.js.map +1 -1
  611. package/build/dist/Types/Telemetry/LlmCostCatalog.js +484 -0
  612. package/build/dist/Types/Telemetry/LlmCostCatalog.js.map +1 -0
  613. package/build/dist/Types/Telemetry/ServiceType.js +1 -0
  614. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  615. package/build/dist/Types/Telemetry/TelemetryRetentionConfig.js.map +1 -1
  616. package/build/dist/Types/Telemetry/TelemetryType.js +1 -0
  617. package/build/dist/Types/Telemetry/TelemetryType.js.map +1 -1
  618. package/build/dist/Types/TwoFactorAuthStatus.js +41 -0
  619. package/build/dist/Types/TwoFactorAuthStatus.js.map +1 -0
  620. package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js +16 -2
  621. package/build/dist/UI/Components/BulkUpdate/BulkArchiveActions.js.map +1 -1
  622. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +15 -1
  623. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
  624. package/build/dist/UI/Components/BulkUpdate/BulkOwnerActions.js +20 -1
  625. package/build/dist/UI/Components/BulkUpdate/BulkOwnerActions.js.map +1 -1
  626. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +1 -1
  627. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  628. package/build/dist/UI/Components/Button/Button.js +22 -1
  629. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  630. package/build/dist/UI/Components/Card/Card.js +1 -1
  631. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  632. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +14 -1
  633. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  634. package/build/dist/UI/Components/Dictionary/DictionaryFilterOperator.js +47 -0
  635. package/build/dist/UI/Components/Dictionary/DictionaryFilterOperator.js.map +1 -1
  636. package/build/dist/UI/Components/DuplicateModel/DuplicateModel.js +8 -0
  637. package/build/dist/UI/Components/DuplicateModel/DuplicateModel.js.map +1 -1
  638. package/build/dist/UI/Components/Forms/ModelForm.js +40 -1
  639. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  640. package/build/dist/UI/Components/List/ListRow.js +4 -1
  641. package/build/dist/UI/Components/List/ListRow.js.map +1 -1
  642. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +32 -7
  643. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
  644. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +2 -17
  645. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  646. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js +93 -4
  647. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js.map +1 -1
  648. package/build/dist/UI/Components/ModelDelete/ModelDelete.js +13 -0
  649. package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
  650. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +27 -11
  651. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  652. package/build/dist/UI/Components/ModelList/ModelList.js +13 -2
  653. package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
  654. package/build/dist/UI/Components/ModelList/StaticModelList.js +4 -1
  655. package/build/dist/UI/Components/ModelList/StaticModelList.js.map +1 -1
  656. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +101 -40
  657. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  658. package/build/dist/UI/Components/ModelTable/ModelTable.js +9 -7
  659. package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
  660. package/build/dist/UI/Components/ModelTable/TableView.js +32 -4
  661. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
  662. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +19 -2
  663. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  664. package/build/dist/UI/Components/OrderedStatesList/Item.js +4 -1
  665. package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
  666. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +33 -32
  667. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  668. package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js +8 -0
  669. package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js.map +1 -1
  670. package/build/dist/UI/Components/SavedViews/SavedViewsFacetSection.js +98 -0
  671. package/build/dist/UI/Components/SavedViews/SavedViewsFacetSection.js.map +1 -0
  672. package/build/dist/UI/Components/SavedViews/SavedViewsList.js +99 -0
  673. package/build/dist/UI/Components/SavedViews/SavedViewsList.js.map +1 -0
  674. package/build/dist/UI/Components/SavedViews/SavedViewsSearchInput.js +17 -0
  675. package/build/dist/UI/Components/SavedViews/SavedViewsSearchInput.js.map +1 -0
  676. package/build/dist/UI/Components/SavedViews/SavedViewsShowMoreButton.js +15 -0
  677. package/build/dist/UI/Components/SavedViews/SavedViewsShowMoreButton.js.map +1 -0
  678. package/build/dist/UI/Components/Table/TableRow.js +8 -2
  679. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  680. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js +93 -4
  681. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js.map +1 -1
  682. package/build/dist/UI/Types/UseComponentOutsideClick.js +39 -0
  683. package/build/dist/UI/Types/UseComponentOutsideClick.js.map +1 -1
  684. package/build/dist/UI/Utils/PermissionGate.js +164 -0
  685. package/build/dist/UI/Utils/PermissionGate.js.map +1 -0
  686. package/build/dist/Utils/Dashboard/Components/DashboardSecurityEventsFlowComponent.js +70 -0
  687. package/build/dist/Utils/Dashboard/Components/DashboardSecurityEventsFlowComponent.js.map +1 -0
  688. package/build/dist/Utils/Dashboard/Components/DashboardSecurityEventsListComponent.js +92 -0
  689. package/build/dist/Utils/Dashboard/Components/DashboardSecurityEventsListComponent.js.map +1 -0
  690. package/build/dist/Utils/Dashboard/Components/Index.js +8 -0
  691. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  692. package/build/dist/Utils/Measurement/MeasurementEvaluator.js +210 -0
  693. package/build/dist/Utils/Measurement/MeasurementEvaluator.js.map +1 -0
  694. package/build/dist/Utils/Monitor/MonitorSummarySnapshotUtil.js +1 -0
  695. package/build/dist/Utils/Monitor/MonitorSummarySnapshotUtil.js.map +1 -1
  696. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +51 -10
  697. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -1
  698. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js +108 -0
  699. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js.map +1 -0
  700. package/build/dist/Utils/SecurityEvent/GenericNormalizer.js +176 -0
  701. package/build/dist/Utils/SecurityEvent/GenericNormalizer.js.map +1 -0
  702. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +146 -0
  703. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -0
  704. package/build/dist/Utils/SecurityEvent/NormalizerHelpers.js +196 -0
  705. package/build/dist/Utils/SecurityEvent/NormalizerHelpers.js.map +1 -0
  706. package/build/dist/Utils/SecurityEvent/OcsfNormalizer.js +136 -0
  707. package/build/dist/Utils/SecurityEvent/OcsfNormalizer.js.map +1 -0
  708. package/build/dist/Utils/SecurityEvent/SecurityEventNormalizer.js +64 -0
  709. package/build/dist/Utils/SecurityEvent/SecurityEventNormalizer.js.map +1 -0
  710. package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js +388 -0
  711. package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js.map +1 -0
  712. package/build/dist/Utils/SecurityEvent/UdmNormalizer.js +328 -0
  713. package/build/dist/Utils/SecurityEvent/UdmNormalizer.js.map +1 -0
  714. package/build/dist/Utils/Telemetry/CrossSignalScope.js +29 -7
  715. package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
  716. package/build/dist/Utils/Telemetry/LogErrorPattern.js +284 -0
  717. package/build/dist/Utils/Telemetry/LogErrorPattern.js.map +1 -0
  718. package/package.json +3 -1
@@ -0,0 +1,672 @@
1
+ import Redis, { ClientType } from "../Infrastructure/Redis";
2
+ import {
3
+ ExpressRequest,
4
+ ExpressResponse,
5
+ NextFunction,
6
+ } from "../Utils/Express";
7
+ import logger from "../Utils/Logger";
8
+ import resolveTrustedClientIp, { ClientIpRequestLike } from "../Utils/ClientIp";
9
+ import Response from "../Utils/Response";
10
+ import ServiceUnavailableException from "../../Types/Exception/ServiceUnavailableException";
11
+ import TooManyRequestsException from "../../Types/Exception/TooManyRequestsException";
12
+
13
+ /*
14
+ * Attempt limiting for the anonymous identity routes that accept a
15
+ * credential: POST /login, POST /verify-totp-auth, POST /verify-webauthn-auth
16
+ * and POST /verify-totp-enrolment
17
+ * (App/FeatureSet/Identity/API/Authentication.ts).
18
+ *
19
+ * WHY THESE ROUTES NEED IT
20
+ *
21
+ * All three are unauthenticated by definition -- they are how a session is
22
+ * obtained -- so nothing upstream of them counts anything. Until this
23
+ * middleware existed a caller could submit credentials to them as fast as the
24
+ * process would answer.
25
+ *
26
+ * /verify-totp-auth is the sharpest case. It is reached with a valid password
27
+ * already in hand, and the only thing left to produce is a six digit code, so
28
+ * unthrottled it is an online guessing oracle against a 10^6 space. The space
29
+ * is not even 10^6 wide at any given instant: Common/Server/Utils/TotpAuth.ts
30
+ * accepts TotpValidationWindow = 3 steps either side of now (seven 30 second
31
+ * steps, +/- 90 seconds) across both entries in SupportedTotpAlgorithms, so
32
+ * fourteen distinct six digit strings are live at once and a single guess
33
+ * lands with probability ~1.4e-5. At a few thousand requests a second that is
34
+ * a bypassed second factor in minutes. Bounded to the budgets below it is
35
+ * years, and the account owner sees the failures.
36
+ *
37
+ * /login is the same shape one step earlier, against a password rather than a
38
+ * code.
39
+ *
40
+ * /verify-webauthn-auth and /verify-totp-enrolment are covered for a reason
41
+ * that holds whatever their own factor is worth. All four routes share one
42
+ * `login()` function and all of them run the same `verifyHashedColumnValue`
43
+ * before they reach their factor, so each is a password oracle in its own
44
+ * right. Leaving any one of them unlimited would not be an unguarded route so
45
+ * much as a hole in the fence: an attacker refused at /login points the same
46
+ * guesses at whichever sibling still answers. The enrolment route makes that
47
+ * concrete -- guessing its CODE is pointless, because /login hands the user
48
+ * the secret it is derived from, but guessing the PASSWORD it demands first is
49
+ * exactly as useful there as anywhere else.
50
+ *
51
+ * CAPTCHA IS NOT THIS
52
+ *
53
+ * /login already calls CaptchaUtil.verifyCaptcha, but that is not a
54
+ * substitute on either axis. CAPTCHA_ENABLED is off by default, so a
55
+ * self-hosted instance has nothing there at all; and an hCaptcha token is
56
+ * single use, which is exactly why the second step of a login cannot demand
57
+ * one -- /verify-totp-auth deliberately does not, and could not.
58
+ *
59
+ * THIS FAILS CLOSED
60
+ *
61
+ * With Redis unreachable these routes answer 503 rather than running
62
+ * unthrottled. That is the choice PublicDashboardRateLimit makes for
63
+ * /master-password and the opposite of the one VerificationCodeRateLimit
64
+ * makes, and the deciding question is the same in all three: is there another
65
+ * control still standing? Here there is not. Nothing in Postgres counts login
66
+ * attempts, so serving the route without the counter means serving the
67
+ * unlimited guessing oracle this middleware exists to close.
68
+ *
69
+ * It also costs nothing in availability that was not already lost. A
70
+ * successful login goes through AccessTokenService.refreshUserAllPermissions,
71
+ * which writes the user's permissions to GlobalCache, which throws
72
+ * DatabaseNotConnectedException when Redis is down. Logging in is already
73
+ * impossible in that state; the difference this makes is a 503 that says to
74
+ * come back shortly instead of a 500.
75
+ */
76
+
77
+ /*
78
+ * Every request consumes TWO counters, and either one can reject it:
79
+ *
80
+ * - the account counter, keyed on the submitted email address AND the client
81
+ * address. This is the budget one person gets for one account.
82
+ *
83
+ * - the address counter, keyed on the client address alone. Without it the
84
+ * account counter is trivially bypassed: the email address is a field in
85
+ * the request body, so a caller who changes it on every request lands in a
86
+ * fresh bucket every time. Against /verify-totp-auth that matters
87
+ * enormously -- a code guessed against ANY account is a bypassed second
88
+ * factor, the attacker does not care whose. The address counter is the
89
+ * ceiling that survives email rotation.
90
+ *
91
+ * Deliberately NOT keyed on the email address alone. A bare per-account
92
+ * counter is a lockout weapon: anyone who knows a victim's email address
93
+ * could burn that account's whole budget from anywhere and keep the real
94
+ * owner out for as long as they cared to keep sending. Pairing the address
95
+ * in means an attacker can only spend their own bucket.
96
+ *
97
+ * The cost of that pairing, stated plainly: an attacker with many source
98
+ * addresses gets a fresh per-account budget from each one, so a distributed
99
+ * attack on a single account is bounded only by how many addresses they have.
100
+ * That is the standard trade and it is the right way round -- the alternative
101
+ * hands every user a remote lockout button, and the distributed case is what
102
+ * the account owner's own failed-login visibility and the network layer are
103
+ * for.
104
+ *
105
+ * Both counters are incremented on every request including a rejected one.
106
+ * That is standard fixed-window behaviour and it is deliberate: a caller who
107
+ * keeps hammering keeps their window pinned rather than being handed a fresh
108
+ * allowance for free.
109
+ */
110
+ export enum IdentityRateLimitBucket {
111
+ /* POST /login. Password guessing. */
112
+ Login = "login",
113
+
114
+ /*
115
+ * POST /verify-totp-auth, POST /verify-webauthn-auth and
116
+ * POST /verify-totp-enrolment -- the second step, reached with a valid
117
+ * password already accepted.
118
+ */
119
+ TwoFactor = "two-factor",
120
+ }
121
+
122
+ export enum IdentityRateLimitScope {
123
+ /* One email address, from one client address. */
124
+ Account = "account",
125
+
126
+ /* One client address, across every account. Survives email rotation. */
127
+ Ip = "ip",
128
+ }
129
+
130
+ export enum IdentityRateLimitOutcome {
131
+ Allowed = "allowed",
132
+ RateLimited = "rate-limited",
133
+
134
+ /* Redis is unreachable, so no limit can be honoured either way. */
135
+ CounterUnavailable = "counter-unavailable",
136
+ }
137
+
138
+ export interface IdentityRateLimitDecision {
139
+ outcome: IdentityRateLimitOutcome;
140
+ retryAfterSeconds?: number | undefined;
141
+
142
+ /* Which counter rejected, for logs. Unset unless rejected. */
143
+ scope?: IdentityRateLimitScope | undefined;
144
+
145
+ /*
146
+ * True only on the request that first crossed the line in this window.
147
+ *
148
+ * The point of a limiter is that the caller keeps knocking, so logging
149
+ * every refusal turns a flood into a second flood in the log pipeline --
150
+ * the tool an operator needs to see the first one. Logging only the
151
+ * crossing gives exactly one line per key per window.
152
+ */
153
+ isFirstRejectionInWindow?: boolean | undefined;
154
+ }
155
+
156
+ const parsePositiveIntFromEnv: (envKey: string, fallback: number) => number = (
157
+ envKey: string,
158
+ fallback: number,
159
+ ): number => {
160
+ const rawValue: string | undefined = process.env[envKey];
161
+
162
+ if (!rawValue) {
163
+ return fallback;
164
+ }
165
+
166
+ const parsedValue: number = parseInt(rawValue, 10);
167
+
168
+ if (!Number.isFinite(parsedValue) || parsedValue <= 0) {
169
+ return fallback;
170
+ }
171
+
172
+ return parsedValue;
173
+ };
174
+
175
+ interface BucketConfig {
176
+ windowSeconds: number;
177
+ perAccountLimit: number;
178
+ perIpLimit: number;
179
+ }
180
+
181
+ /*
182
+ * Password budget.
183
+ *
184
+ * Ten attempts per quarter hour for one account from one address. A person
185
+ * who has forgotten which of their passwords this is tries three or four and
186
+ * then uses the reset link; ten is comfortably past that and still turns
187
+ * "as fast as the process answers" into forty an hour.
188
+ *
189
+ * The per-address ceiling is set for the honest worst case rather than the
190
+ * typical one, because a corporate NAT puts a whole office behind a single
191
+ * address and a morning sign-in surge must not be refused. 150 a quarter hour
192
+ * covers that while still bounding a caller who rotates email addresses to
193
+ * fifteen accounts' worth of attempts -- and it is the number an operator
194
+ * most likely wants to lower, which is what the environment variable is for.
195
+ * A limiter that fires on real users gets switched off, and a switched-off
196
+ * limiter bounds nothing.
197
+ */
198
+ const LOGIN_BUCKET: BucketConfig = {
199
+ windowSeconds: parsePositiveIntFromEnv(
200
+ "IDENTITY_LOGIN_RATE_LIMIT_WINDOW_SECONDS",
201
+ 15 * 60,
202
+ ),
203
+ perAccountLimit: parsePositiveIntFromEnv(
204
+ "IDENTITY_LOGIN_RATE_LIMIT_PER_ACCOUNT_PER_WINDOW",
205
+ 10,
206
+ ),
207
+ perIpLimit: parsePositiveIntFromEnv(
208
+ "IDENTITY_LOGIN_RATE_LIMIT_PER_IP_PER_WINDOW",
209
+ 150,
210
+ ),
211
+ };
212
+
213
+ /*
214
+ * Second step budget.
215
+ *
216
+ * Same shape as the password bucket, and the same numbers, for a different
217
+ * reason: the code is read off a screen rather than recalled, so ten wrong
218
+ * ones in a quarter hour is already well past anything a real user does --
219
+ * a phone whose clock has drifted past the +/- 90 second window fails every
220
+ * time, and no number of retries fixes that.
221
+ *
222
+ * Kept as a SEPARATE bucket from the password one rather than a shared pool,
223
+ * which does mean a caller gets both budgets in a window. That is the price of
224
+ * the property that matters more: a burst of /login noise must not be able to
225
+ * refuse a user who is midway through finishing a two factor login, and a user
226
+ * being marched through a mandated enrolment must not be locked out of it by
227
+ * the /login attempt that sent them there.
228
+ *
229
+ * What ten buys against guessing: fourteen of the 10^6 codes are live at any
230
+ * instant, so forty guesses an hour is a ~0.06% chance of landing one in a
231
+ * day and about a year to reach even odds -- against an attacker who holds
232
+ * the account's password for that entire year and generates a visible failed
233
+ * attempt every ninety seconds throughout.
234
+ */
235
+ const TWO_FACTOR_BUCKET: BucketConfig = {
236
+ windowSeconds: parsePositiveIntFromEnv(
237
+ "IDENTITY_TWO_FACTOR_RATE_LIMIT_WINDOW_SECONDS",
238
+ 15 * 60,
239
+ ),
240
+ perAccountLimit: parsePositiveIntFromEnv(
241
+ "IDENTITY_TWO_FACTOR_RATE_LIMIT_PER_ACCOUNT_PER_WINDOW",
242
+ 10,
243
+ ),
244
+ perIpLimit: parsePositiveIntFromEnv(
245
+ "IDENTITY_TWO_FACTOR_RATE_LIMIT_PER_IP_PER_WINDOW",
246
+ 150,
247
+ ),
248
+ };
249
+
250
+ const KEY_PREFIX: string = "identity:rl:";
251
+
252
+ /*
253
+ * Counter keys outlive their window by one full window, so a request landing
254
+ * on a boundary cannot read a key that was reclaimed mid-window.
255
+ */
256
+ const TTL_MULTIPLIER: number = 2;
257
+
258
+ /* Bounds a Redis key built from caller-supplied values. */
259
+ const MAX_KEY_SEGMENT_LENGTH: number = 64;
260
+
261
+ /* How often the "counter unavailable" condition may be logged, per bucket. */
262
+ const COUNTER_UNAVAILABLE_LOG_INTERVAL_MS: number = 60 * 1000;
263
+
264
+ export default class IdentityRateLimit {
265
+ /*
266
+ * The client address to bill this request to.
267
+ *
268
+ * Delegates to the shared ClientIp helper, which reads X-Forwarded-For from
269
+ * the trusted (right-hand) end under the instance-wide TRUSTED_PROXY_HOPS
270
+ * setting. Deliberately NOT Express.getClientIp: that one takes the LEFTMOST
271
+ * entry, which any caller can set by sending its own X-Forwarded-For header,
272
+ * and for a rate limiter that is fatal -- a fresh spoofed value per request
273
+ * is a fresh bucket per request and therefore no limit at all.
274
+ *
275
+ * The helper also normalizes ports, brackets and IPv4-mapped IPv6, so one
276
+ * caller cannot land in two different buckets depending on the form their
277
+ * address arrives in.
278
+ */
279
+ public static resolveClientIp(req: ExpressRequest): string {
280
+ const clientIp: string | undefined = resolveTrustedClientIp(
281
+ req as unknown as ClientIpRequestLike,
282
+ );
283
+
284
+ if (clientIp) {
285
+ return IdentityRateLimit.sanitizeKeySegment(clientIp);
286
+ }
287
+
288
+ /*
289
+ * Everything with no resolvable address shares one bucket. That is the
290
+ * conservative direction: an unidentifiable caller should not be handed a
291
+ * private allowance.
292
+ */
293
+ return "unknown";
294
+ }
295
+
296
+ /*
297
+ * The account this request is trying to authenticate as, as a key segment.
298
+ *
299
+ * The login page posts everything nested under `data` (see
300
+ * App/FeatureSet/Accounts/src/Pages/Login.tsx), which is where all four
301
+ * routes read the credentials from; the top level is checked too so that a
302
+ * caller posting the flatter shape is still counted rather than silently
303
+ * sharing the "none" bucket with everybody else.
304
+ *
305
+ * `email` ARRIVES IN TWO SHAPES, AND BOTH ARE FIRST-PARTY
306
+ *
307
+ * A bare string, and the serialized SerializableObject envelope
308
+ * `{ _type: "Email", value: "..." }` that Email.toJSON produces. Which one
309
+ * turns up depends on how the caller was written, and the shipped clients
310
+ * disagree with each other on the very routes limited here:
311
+ *
312
+ * - POST /login from the dashboard goes through ModelForm, which hands the
313
+ * model to ModelAPI.createOrUpdate, which sends
314
+ * JSONFunctions.serialize(BaseModel.toJSON(...)) -- the ENVELOPE.
315
+ * - POST /login from the mobile app hand-builds the same envelope
316
+ * (MobileApp/src/api/auth.ts).
317
+ * - POST /verify-totp-auth, /verify-totp-enrolment and
318
+ * /verify-webauthn-auth from the dashboard spread the raw form values
319
+ * (`...initialValues`), so there `email` is a bare STRING.
320
+ *
321
+ * The handler does not care, because BaseModel.fromJSON resolves both to the
322
+ * same address -- so this must not care either. Reading only the string form
323
+ * would put every /login from every shipped client into the shared "none"
324
+ * bucket, which is not a small mistake in either direction: the per-account
325
+ * counter would degenerate into a SECOND per-address counter at the much
326
+ * tighter per-account limit, refusing a whole office (or a carrier NAT) after
327
+ * ten sign-ins rather than the hundred and fifty the per-address ceiling is
328
+ * deliberately sized for; and, because the two shapes would key differently,
329
+ * an attacker could take the per-account budget twice by alternating them.
330
+ *
331
+ * The unwrap is deliberately not gated on `_type` being exactly Email. Any
332
+ * object carrying a string `value` is keyed by that value, which is the safe
333
+ * direction: the worst case is counting a request the handler will reject
334
+ * anyway against the bucket it names, whereas gating narrowly leaves another
335
+ * shape sitting in "none" for someone to spend.
336
+ *
337
+ * Lower-cased, because otherwise Bob@example.com and bob@example.com are
338
+ * two buckets for one account and case alone buys a fresh allowance. No
339
+ * attempt is made to validate the address: a well-formed one that belongs
340
+ * to nobody is worth exactly as much to an attacker as a malformed one, so
341
+ * there is nothing for a format check to separate. Normalizing is the part
342
+ * that matters.
343
+ */
344
+ public static resolveAccountKey(req: ExpressRequest): string {
345
+ const body: Record<string, unknown> | undefined = req.body as
346
+ | Record<string, unknown>
347
+ | undefined;
348
+
349
+ const data: Record<string, unknown> | undefined =
350
+ body && typeof body["data"] === "object" && body["data"] !== null
351
+ ? (body["data"] as Record<string, unknown>)
352
+ : undefined;
353
+
354
+ const field: unknown = data?.["email"] ?? body?.["email"];
355
+
356
+ /*
357
+ * Arrays are typeof "object" too, and indexing one by "value" is
358
+ * undefined rather than a throw -- but excluding them keeps the intent
359
+ * legible and stops a caller smuggling anything odd through.
360
+ */
361
+ const raw: unknown =
362
+ field && typeof field === "object" && !Array.isArray(field)
363
+ ? (field as Record<string, unknown>)["value"]
364
+ : field;
365
+
366
+ /*
367
+ * `email` is whatever JSON the caller sent, so it is only a string
368
+ * because they chose to make it one. A number, a nested object or a
369
+ * missing field must land in a bucket rather than throw.
370
+ */
371
+ if (typeof raw !== "string" || raw.trim().length === 0) {
372
+ return "none";
373
+ }
374
+
375
+ return IdentityRateLimit.sanitizeKeySegment(raw.trim().toLowerCase());
376
+ }
377
+
378
+ private static sanitizeKeySegment(value: string): string {
379
+ return (
380
+ value
381
+ .slice(0, MAX_KEY_SEGMENT_LENGTH)
382
+ /*
383
+ * Redis keys are binary safe, but a predictable charset keeps
384
+ * operational tooling (SCAN patterns, dashboards) sane.
385
+ */
386
+ .replace(/[^a-zA-Z0-9._:%\-[\]@]/g, "_")
387
+ );
388
+ }
389
+
390
+ public static getBucketConfig(bucket: IdentityRateLimitBucket): BucketConfig {
391
+ return bucket === IdentityRateLimitBucket.TwoFactor
392
+ ? TWO_FACTOR_BUCKET
393
+ : LOGIN_BUCKET;
394
+ }
395
+
396
+ /*
397
+ * Increment both counters for this request and decide.
398
+ *
399
+ * Both INCRs go out in one pipeline so the common path costs a single round
400
+ * trip; the EXPIRE follow-ups only happen on the request that created a key.
401
+ */
402
+ public static async consume(data: {
403
+ accountKey: string;
404
+ clientIp: string;
405
+ bucket: IdentityRateLimitBucket;
406
+ }): Promise<IdentityRateLimitDecision> {
407
+ const client: ClientType | null = Redis.getClient();
408
+
409
+ if (!client || !Redis.isConnected()) {
410
+ return { outcome: IdentityRateLimitOutcome.CounterUnavailable };
411
+ }
412
+
413
+ const config: BucketConfig = IdentityRateLimit.getBucketConfig(data.bucket);
414
+
415
+ const windowMs: number = config.windowSeconds * 1000;
416
+ const windowIndex: number = Math.floor(Date.now() / windowMs);
417
+
418
+ const accountCounterKey: string = `${KEY_PREFIX}${data.bucket}:a:${data.accountKey}:${data.clientIp}:${windowIndex}`;
419
+ const ipCounterKey: string = `${KEY_PREFIX}${data.bucket}:i:${data.clientIp}:${windowIndex}`;
420
+
421
+ try {
422
+ const pipelineResults: Array<[Error | null, unknown]> | null =
423
+ (await client
424
+ .pipeline()
425
+ .incr(accountCounterKey)
426
+ .incr(ipCounterKey)
427
+ .exec()) as Array<[Error | null, unknown]> | null;
428
+
429
+ if (!pipelineResults || pipelineResults.length < 2) {
430
+ throw new Error("Rate limit pipeline returned no result");
431
+ }
432
+
433
+ const accountCount: number = IdentityRateLimit.readCounterResult(
434
+ pipelineResults[0],
435
+ );
436
+ const ipCount: number = IdentityRateLimit.readCounterResult(
437
+ pipelineResults[1],
438
+ );
439
+
440
+ /*
441
+ * Set the expiry only on the write that created the key. Re-issuing
442
+ * EXPIRE on every increment would slide the window forward for as long
443
+ * as the attempts continue, so the counter would never reset and a
444
+ * caller who tripped the limit once could never recover -- which on a
445
+ * login route is a permanent lockout, not a slowdown.
446
+ */
447
+ const ttlSeconds: number = config.windowSeconds * TTL_MULTIPLIER;
448
+ const keysToExpire: Array<string> = [];
449
+
450
+ if (accountCount === 1) {
451
+ keysToExpire.push(accountCounterKey);
452
+ }
453
+
454
+ if (ipCount === 1) {
455
+ keysToExpire.push(ipCounterKey);
456
+ }
457
+
458
+ if (keysToExpire.length > 0) {
459
+ const expirePipeline: ReturnType<ClientType["pipeline"]> =
460
+ client.pipeline();
461
+
462
+ for (const key of keysToExpire) {
463
+ expirePipeline.expire(key, ttlSeconds);
464
+ }
465
+
466
+ await expirePipeline.exec();
467
+ }
468
+
469
+ const retryAfterSeconds: number =
470
+ IdentityRateLimit.getSecondsUntilWindowEnd(config.windowSeconds);
471
+
472
+ /*
473
+ * The account counter is reported first when both are over, because it
474
+ * is the more specific of the two and the more useful thing to see in a
475
+ * log line.
476
+ */
477
+ if (accountCount > config.perAccountLimit) {
478
+ return {
479
+ outcome: IdentityRateLimitOutcome.RateLimited,
480
+ retryAfterSeconds,
481
+ scope: IdentityRateLimitScope.Account,
482
+ isFirstRejectionInWindow: accountCount === config.perAccountLimit + 1,
483
+ };
484
+ }
485
+
486
+ if (ipCount > config.perIpLimit) {
487
+ return {
488
+ outcome: IdentityRateLimitOutcome.RateLimited,
489
+ retryAfterSeconds,
490
+ scope: IdentityRateLimitScope.Ip,
491
+ isFirstRejectionInWindow: ipCount === config.perIpLimit + 1,
492
+ };
493
+ }
494
+
495
+ return { outcome: IdentityRateLimitOutcome.Allowed };
496
+ } catch (err) {
497
+ /*
498
+ * Throttled: whatever broke Redis is unlikely to have broken it for one
499
+ * request only, and a per-request log line buries the incident it is
500
+ * reporting.
501
+ */
502
+ if (IdentityRateLimit.shouldLogCounterUnavailable(data.bucket)) {
503
+ logger.warn(
504
+ `IdentityRateLimit: counter failed for ${data.bucket} request from ${data.clientIp}`,
505
+ );
506
+ logger.warn(err);
507
+ }
508
+
509
+ return { outcome: IdentityRateLimitOutcome.CounterUnavailable };
510
+ }
511
+ }
512
+
513
+ private static readCounterResult(
514
+ result: [Error | null, unknown] | undefined,
515
+ ): number {
516
+ if (!result) {
517
+ throw new Error("Rate limit counter returned no result");
518
+ }
519
+
520
+ const [error, value] = result;
521
+
522
+ if (error) {
523
+ throw error;
524
+ }
525
+
526
+ if (typeof value !== "number") {
527
+ throw new Error("Rate limit counter returned a non-numeric value");
528
+ }
529
+
530
+ return value;
531
+ }
532
+
533
+ /*
534
+ * Remaining seconds in the current fixed window, so every rejected caller
535
+ * is told to come back when the window actually rolls rather than all
536
+ * backing off by the same constant and re-colliding.
537
+ */
538
+ private static getSecondsUntilWindowEnd(windowSeconds: number): number {
539
+ const windowMs: number = windowSeconds * 1000;
540
+ const msIntoWindow: number = Date.now() % windowMs;
541
+
542
+ return Math.max(1, Math.ceil((windowMs - msIntoWindow) / 1000));
543
+ }
544
+
545
+ /*
546
+ * Express middleware. Registered as the first handler on each credential
547
+ * route, so a flood is refused before it costs a user lookup -- and, on the
548
+ * password routes, before it costs the bcrypt verify that makes each guess
549
+ * expensive for us as well as for the attacker.
550
+ */
551
+ public static getMiddleware(
552
+ bucket: IdentityRateLimitBucket,
553
+ ): (
554
+ req: ExpressRequest,
555
+ res: ExpressResponse,
556
+ next: NextFunction,
557
+ ) => Promise<void> {
558
+ return async (
559
+ req: ExpressRequest,
560
+ res: ExpressResponse,
561
+ next: NextFunction,
562
+ ): Promise<void> => {
563
+ const accountKey: string = IdentityRateLimit.resolveAccountKey(req);
564
+ const clientIp: string = IdentityRateLimit.resolveClientIp(req);
565
+
566
+ const decision: IdentityRateLimitDecision =
567
+ await IdentityRateLimit.consume({
568
+ accountKey,
569
+ clientIp,
570
+ bucket,
571
+ });
572
+
573
+ if (decision.outcome === IdentityRateLimitOutcome.RateLimited) {
574
+ if (decision.retryAfterSeconds) {
575
+ IdentityRateLimit.setRetryAfterHeader(
576
+ res,
577
+ decision.retryAfterSeconds,
578
+ );
579
+ }
580
+
581
+ if (decision.isFirstRejectionInWindow) {
582
+ logger.warn(
583
+ `IdentityRateLimit: rejected ${bucket} attempt for ${accountKey} from ${clientIp} (${decision.scope} limit)`,
584
+ );
585
+ }
586
+
587
+ /*
588
+ * The same message whichever counter fired, and whether or not the
589
+ * account exists. These routes are careful not to say which half of a
590
+ * credential was wrong; a limiter that answered differently for a real
591
+ * address than for an invented one would hand back the account
592
+ * enumeration the handlers withhold.
593
+ */
594
+ return Response.sendErrorResponse(
595
+ req,
596
+ res,
597
+ new TooManyRequestsException(
598
+ "Too many sign-in attempts. Please try again later.",
599
+ ),
600
+ );
601
+ }
602
+
603
+ if (decision.outcome === IdentityRateLimitOutcome.CounterUnavailable) {
604
+ /*
605
+ * Fails closed. See the note at the top of this file: the counter is
606
+ * the only thing bounding guesses on these routes, and a login cannot
607
+ * complete without Redis anyway.
608
+ */
609
+ if (IdentityRateLimit.shouldLogCounterUnavailable(bucket)) {
610
+ logger.error(
611
+ `IdentityRateLimit: rate limit counter unavailable, refusing ${bucket} attempts`,
612
+ );
613
+ }
614
+
615
+ return Response.sendErrorResponse(
616
+ req,
617
+ res,
618
+ new ServiceUnavailableException(
619
+ "Unable to sign you in right now. Please try again shortly.",
620
+ ),
621
+ );
622
+ }
623
+
624
+ return next();
625
+ };
626
+ }
627
+
628
+ /*
629
+ * A Redis outage means EVERY request takes the unavailable path, so an
630
+ * unguarded log line there is one per request for as long as the outage
631
+ * lasts -- the same log-flooding problem the crossing-only rejection log
632
+ * avoids, but continuous. One line per bucket per interval is enough to
633
+ * make the condition visible without burying everything else.
634
+ */
635
+ private static shouldLogCounterUnavailable(
636
+ bucket: IdentityRateLimitBucket,
637
+ ): boolean {
638
+ const now: number = Date.now();
639
+ const lastLoggedAt: number =
640
+ IdentityRateLimit.counterUnavailableLastLoggedAt.get(bucket) || 0;
641
+
642
+ if (now - lastLoggedAt < COUNTER_UNAVAILABLE_LOG_INTERVAL_MS) {
643
+ return false;
644
+ }
645
+
646
+ IdentityRateLimit.counterUnavailableLastLoggedAt.set(bucket, now);
647
+
648
+ return true;
649
+ }
650
+
651
+ private static counterUnavailableLastLoggedAt: Map<
652
+ IdentityRateLimitBucket,
653
+ number
654
+ > = new Map();
655
+
656
+ private static setRetryAfterHeader(
657
+ res: ExpressResponse,
658
+ retryAfterSeconds: number,
659
+ ): void {
660
+ const setHeader: unknown = (res as unknown as Record<string, unknown>)[
661
+ "setHeader"
662
+ ];
663
+
664
+ if (typeof setHeader === "function") {
665
+ (setHeader as (name: string, value: string) => void).call(
666
+ res,
667
+ "Retry-After",
668
+ String(retryAfterSeconds),
669
+ );
670
+ }
671
+ }
672
+ }
@@ -192,10 +192,23 @@ export class AccessTokenService extends BaseService {
192
192
  });
193
193
  }
194
194
 
195
- const permission: UserTenantAccessPermission =
195
+ const defaultPermission: UserTenantAccessPermission =
196
196
  UserPermissionUtil.getDefaultUserTenantAccessPermission(projectId);
197
197
 
198
- permission.permissions = permission.permissions.concat(userPermissions);
198
+ defaultPermission.permissions =
199
+ defaultPermission.permissions.concat(userPermissions);
200
+
201
+ /*
202
+ * Reaching here means the user holds an accepted membership in at least one
203
+ * team of this project, so they are a project member whatever roles those
204
+ * teams carry - the empty-team case returned above. `ProjectUser` says
205
+ * exactly that, and shared workspace resources - saved table views, labels,
206
+ * teams, member rows - are read through it. Without it a user scoped to a
207
+ * single domain (Monitor Viewer and nothing else) cannot load the tables
208
+ * that role exists to give them.
209
+ */
210
+ const permission: UserTenantAccessPermission =
211
+ UserPermissionUtil.withProjectUserPermission(defaultPermission);
199
212
 
200
213
  await GlobalCache.setJSON(
201
214
  PermissionNamespace.ProjectPermission,