@oneuptime/common 12.0.33 → 13.0.0
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.
- package/Models/AnalyticsModels/RumSession.ts +117 -1
- package/Models/AnalyticsModels/RumSessionChunk.ts +13 -0
- package/Models/DatabaseModels/AlertCustomField.ts +77 -3
- package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
- package/Models/DatabaseModels/GlobalConfig.ts +12 -12
- package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
- package/Models/DatabaseModels/InventoryItem.ts +44 -1
- package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
- package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
- package/Models/DatabaseModels/NetworkDevice.ts +126 -0
- package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
- package/Models/DatabaseModels/RumApplication.ts +6 -6
- package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
- package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamMember.ts +0 -9
- package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
- package/Models/DatabaseModels/TeamPermission.ts +3 -24
- package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
- package/Models/DatabaseModels/UserTelegram.ts +0 -4
- package/Scripts/benchmark-fanin-capacity.js +181 -0
- package/Server/API/TelemetryAPI.ts +1284 -164
- package/Server/API/UserNotificationSettingAPI.ts +55 -0
- package/Server/API/UserTelegramAPI.ts +48 -4
- package/Server/EnvironmentConfig.ts +82 -18
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Infrastructure/QueueWorker.ts +20 -14
- package/Server/Infrastructure/Redis.ts +8 -8
- package/Server/Infrastructure/Semaphore.ts +2 -0
- package/Server/Infrastructure/Status.ts +10 -4
- package/Server/Middleware/TelemetryIngest.ts +453 -7
- package/Server/Services/AccessTokenService.ts +1 -0
- package/Server/Services/AlertCustomFieldService.ts +98 -0
- package/Server/Services/AlertService.ts +37 -0
- package/Server/Services/ApiKeyPermissionService.ts +461 -29
- package/Server/Services/CustomFieldMappingService.ts +879 -0
- package/Server/Services/DatabaseService.ts +65 -13
- package/Server/Services/GlobalConfigService.ts +194 -0
- package/Server/Services/IncidentCustomFieldService.ts +98 -0
- package/Server/Services/IncidentService.ts +35 -0
- package/Server/Services/InventoryItemService.ts +31 -1
- package/Server/Services/MetricService.ts +194 -0
- package/Server/Services/MonitorService.ts +32 -0
- package/Server/Services/MonitorTemplateService.ts +140 -19
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +427 -66
- package/Server/Services/NetworkDeviceDiscoveryScanService.ts +87 -2
- package/Server/Services/NetworkDeviceService.ts +69 -0
- package/Server/Services/ProjectService.ts +22 -0
- package/Server/Services/RoutineEmailSettingsService.ts +73 -0
- package/Server/Services/RumSessionReplayViewService.ts +104 -24
- package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
- package/Server/Services/ScheduledMaintenanceService.ts +32 -0
- package/Server/Services/TeamMemberService.ts +78 -0
- package/Server/Services/TeamPermissionService.ts +235 -3
- package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
- package/Server/Services/UserNotificationRuleService.ts +76 -25
- package/Server/Services/UserNotificationSettingService.ts +34 -6
- package/Server/Services/UserTelegramService.ts +326 -5
- package/Server/Types/Database/Permissions/ReadPermission.ts +45 -5
- package/Server/Types/Database/QueryHelper.ts +2 -0
- package/Server/Types/Database/QueryUtil.ts +56 -0
- package/Server/Types/Markdown.ts +93 -1
- package/Server/Utils/APIKey/AccessPermission.ts +5 -2
- package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
- package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
- package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
- package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +82 -17
- package/Server/Utils/DataSource/EgressGuard.ts +177 -8
- package/Server/Utils/EmailRollup/EmailRollupConstants.ts +38 -5
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +67 -5
- package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +2 -2
- package/Server/Utils/FrontendEnvironment.ts +40 -0
- package/Server/Utils/LogRedaction.ts +20 -0
- package/Server/Utils/Logger.ts +11 -0
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +394 -86
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
- package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +31 -5
- package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +312 -52
- package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +82 -9
- package/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.ts +16 -7
- package/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.ts +29 -17
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +107 -48
- package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +29 -0
- package/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.ts +158 -0
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +27 -0
- package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
- package/Server/Utils/SSRFProtection.ts +217 -10
- package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
- package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
- package/Server/Utils/StartServer.ts +2 -17
- package/Server/Utils/TelegramVerificationToken.ts +185 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +11 -1
- package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +83 -9
- package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
- package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
- package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
- package/Server/Utils/VM/VMAPI.ts +1 -0
- package/Server/Utils/VM/VMRunner.ts +975 -95
- package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
- package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +32 -0
- package/Tests/App/Dashboard/AdoptedDeviceDrawer.test.tsx +374 -0
- package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
- package/Tests/App/Dashboard/DashboardLabelVariables.test.tsx +580 -0
- package/Tests/App/Dashboard/DashboardMonitorLabelVariable.test.tsx +438 -0
- package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +5 -2
- package/Tests/App/Dashboard/DeviceAttachmentCard.test.tsx +273 -0
- package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +505 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +468 -0
- package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +163 -0
- package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +401 -0
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +232 -0
- package/Tests/App/Dashboard/InventoryItems.test.tsx +201 -0
- package/Tests/App/Dashboard/InventoryTypeAndStatusFacets.test.tsx +798 -0
- package/Tests/App/Dashboard/NetworkTopologyLiveView.test.tsx +320 -0
- package/Tests/App/Dashboard/NetworkTopologyToolbar.test.tsx +275 -0
- package/Tests/App/Dashboard/OnCallCalendarFeedEmptyState.test.tsx +975 -0
- package/Tests/App/Dashboard/OnCallCalendarFeedPlanGate.test.tsx +63 -0
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +626 -0
- package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +348 -0
- package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +331 -0
- package/Tests/App/Dashboard/UserSettingsEmailPreferences.test.tsx +603 -0
- package/Tests/App/Dashboard/UserSettingsNotificationSettings.test.tsx +324 -0
- package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +13 -4
- package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
- package/Tests/App/StatusPage/StatusPageOidcOrigin.test.tsx +223 -0
- package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
- package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
- package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
- package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
- package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
- package/Tests/Models/InventoryItemStatus.test.ts +147 -0
- package/Tests/Models/NetworkDeviceMacAddressColumn.test.ts +294 -0
- package/Tests/ResponsiveVisibility.test.ts +115 -0
- package/Tests/ResponsiveVisibility.ts +183 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +129 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
- package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
- package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
- package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
- package/Tests/Server/EnvironmentConfigValkey.test.ts +227 -0
- package/Tests/Server/Infrastructure/Postgres/AddMacAddressToNetworkDeviceMigration.test.ts +365 -0
- package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +241 -0
- package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
- package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
- package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
- package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
- package/Tests/Server/Infrastructure/ValkeyDeploymentConfig.test.ts +265 -0
- package/Tests/Server/Middleware/HttpMetricsMiddleware.test.ts +382 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
- package/Tests/Server/Middleware/SCIMAuthorization.test.ts +525 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
- package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
- package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
- package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
- package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
- package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
- package/Tests/Server/Services/DatabaseServiceAggregateBy.test.ts +291 -56
- package/Tests/Server/Services/DatabaseServiceSortTiebreaker.test.ts +151 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
- package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
- package/Tests/Server/Services/InventoryItemManualCreate.test.ts +105 -0
- package/Tests/Server/Services/InventoryItemPromotionGate.test.ts +178 -0
- package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
- package/Tests/Server/Services/MonitorTemplateServiceCustomFieldSync.test.ts +502 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +1351 -74
- package/Tests/Server/Services/NetworkDeviceDiscoveryScanRegistration.test.ts +520 -0
- package/Tests/Server/Services/NetworkDeviceMacAddressNormalization.test.ts +572 -0
- package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
- package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
- package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
- package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
- package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
- package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +141 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +18 -10
- package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
- package/Tests/Server/Types/Database/InventoryStatusPostgres.test.ts +368 -0
- package/Tests/Server/Types/Database/Permissions/ReadBlockPermission.test.ts +261 -14
- package/Tests/Server/Types/Database/QueryUtilIncludesAnyOfGroups.test.ts +169 -0
- package/Tests/Server/Types/Database/QueryUtilIncludesAnyOfGroupsPostgres.test.ts +297 -0
- package/Tests/Server/Types/Markdown.test.ts +194 -1
- package/Tests/Server/Types/Workflow/Components/IncomingWebhookUtils.test.ts +279 -0
- package/Tests/Server/Types/Workflow/Components/TextToJson.test.ts +212 -0
- package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
- package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
- package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
- package/Tests/Server/Utils/CustomField/CustomFieldMappingRegistry.test.ts +436 -0
- package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +214 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
- package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +2 -2
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +10 -3
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +77 -1
- package/Tests/Server/Utils/EventLoop.test.ts +359 -0
- package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
- package/Tests/Server/Utils/JsonWebToken.test.ts +30 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
- package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
- package/Tests/Server/Utils/Monitor/Criteria/CompareCriteria.test.ts +242 -0
- package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +590 -0
- package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +29 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +30 -6
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +246 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEmailEvalLogAgreement.test.ts +280 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +659 -8
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorMetricUnits.test.ts +570 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaExpectationBuilderUnits.test.ts +30 -5
- package/Tests/Server/Utils/Monitor/MonitorCriteriaMessageBuilderUnits.test.ts +68 -21
- package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +36 -19
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.test.ts +573 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +317 -0
- package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
- package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
- package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
- package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
- package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
- package/Tests/Server/Utils/Telemetry/ContextSpanProcessor.test.ts +281 -0
- package/Tests/Server/Utils/Telemetry/InventoryDuplicateIdentity.test.ts +316 -0
- package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +111 -8
- package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
- package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
- package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
- package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
- package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
- package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
- package/Tests/Types/Database/IncludesAnyOfGroups.test.ts +106 -0
- package/Tests/Types/JSONFunctions.test.ts +300 -0
- package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
- package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
- package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
- package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
- package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
- package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
- package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
- package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
- package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
- package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
- package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
- package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
- package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
- package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
- package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
- package/Tests/Types/NetworkAutomation/AutoImportRunMerge.test.ts +235 -0
- package/Tests/Types/NetworkAutomation/RuleRunResult.test.ts +66 -0
- package/Tests/Types/NetworkAutomation/RuleRunResultDescribe.test.ts +309 -1
- package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
- package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
- package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
- package/Tests/Types/Telemetry/InventoryLiveness.test.ts +99 -0
- package/Tests/Types/WebsiteRequest.test.ts +285 -3
- package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
- package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
- package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
- package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
- package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +160 -0
- package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
- package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
- package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
- package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
- package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
- package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
- package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +28 -12
- package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
- package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
- package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
- package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
- package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
- package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
- package/Tests/UI/ReactRouterSingletonBuild.test.ts +133 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
- package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
- package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
- package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
- package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
- package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
- package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
- package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
- package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
- package/Tests/UI/Rum/ReplayHeader.test.tsx +719 -0
- package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
- package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
- package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
- package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +514 -0
- package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
- package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
- package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
- package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
- package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
- package/Tests/UI/Rum/ReplayTimeFormat.test.ts +94 -0
- package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
- package/Tests/UI/Rum/ReplayUi.test.tsx +559 -0
- package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
- package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
- package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
- package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +5 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +1 -0
- package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
- package/Tests/Utils/API.test.ts +308 -0
- package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +11 -1
- package/Tests/Utils/Dashboard/LabelVariable.test.ts +257 -0
- package/Tests/Utils/Dashboard/VariableUrlState.test.ts +144 -14
- package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
- package/Tests/Utils/MetricUnitUtil.test.ts +81 -0
- package/Tests/Utils/Monitor/DeviceMacLearningUtil.test.ts +497 -0
- package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +546 -0
- package/Tests/Utils/Monitor/MonitorTemplateCustomFieldUtil.test.ts +218 -0
- package/Tests/Utils/Monitor/NetworkTopologyEndpointAdoption.test.ts +1755 -0
- package/Tests/Utils/NetworkAutomation/AutoImportRunChain.test.ts +320 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
- package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
- package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
- package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
- package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
- package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
- package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
- package/Tests/Utils/ValueFormatter.test.ts +148 -0
- package/Types/BaseDatabase/IncludesAnyOfGroups.ts +77 -0
- package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
- package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
- package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardMonitorListComponent.ts +1 -0
- package/Types/Dashboard/DashboardVariable.ts +8 -0
- package/Types/Icon/IconProp.ts +1 -0
- package/Types/JSON.ts +4 -0
- package/Types/JSONFunctions.ts +205 -43
- package/Types/Monitor/CephAlertTemplates.ts +157 -195
- package/Types/Monitor/DockerAlertTemplates.ts +338 -128
- package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
- package/Types/Monitor/HostAlertTemplates.ts +302 -130
- package/Types/Monitor/IotAlertTemplates.ts +112 -104
- package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
- package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
- package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
- package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
- package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
- package/Types/Monitor/RumAlertTemplates.ts +46 -7
- package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
- package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
- package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +13 -0
- package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
- package/Types/NetworkAutomation/RuleRunResult.ts +402 -13
- package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
- package/Types/Rum/SessionReplay.ts +209 -0
- package/Types/Rum/SessionReplayApi.ts +722 -0
- package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
- package/Types/Rum/SessionReplayConsentMode.ts +11 -7
- package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
- package/Types/Rum/SessionReplayHealth.ts +238 -0
- package/Types/SerializableObjectDictionary.ts +4 -0
- package/Types/Telemetry/InventoryLiveness.ts +56 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
- package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
- package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
- package/Types/WebsiteRequest.ts +85 -3
- package/UI/Components/CSVFileUpload/CSVFileUpload.tsx +9 -2
- package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
- package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
- package/UI/Components/Charts/Line/LineChart.tsx +13 -2
- package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
- package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
- package/UI/Components/Charts/Utils/XAxis.ts +217 -0
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +189 -46
- package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
- package/UI/Components/Dashboard/DashboardVariableControl.tsx +285 -0
- package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
- package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
- package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
- package/UI/Components/Header/Header.tsx +25 -9
- package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
- package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
- package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
- package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
- package/UI/Components/Icon/Icon.tsx +11 -0
- package/UI/Components/JSONTable/JSONTable.tsx +2 -2
- package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
- package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
- package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
- package/UI/Components/ModelTable/Column.ts +15 -0
- package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
- package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
- package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
- package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
- package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
- package/UI/Components/Table/CellClassName.ts +81 -0
- package/UI/Components/Table/TableRow.tsx +20 -14
- package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
- package/UI/Components/Table/Types/Column.ts +36 -0
- package/UI/Components/Tooltip/Tooltip.tsx +11 -1
- package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
- package/UI/Components/Workflow/NodePlacement.ts +57 -0
- package/UI/Components/Workflow/Workflow.tsx +47 -18
- package/UI/Config.ts +15 -33
- package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
- package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
- package/UI/Utils/Telemetry/Telemetry.ts +10 -8
- package/UI/esbuild-config.js +6 -0
- package/Utils/API.ts +129 -3
- package/Utils/Dashboard/Components/DashboardMonitorListComponent.ts +12 -1
- package/Utils/Dashboard/LabelVariable.ts +152 -0
- package/Utils/Dashboard/VariableUrlState.ts +27 -5
- package/Utils/HTTPResponseBodyReader.ts +221 -0
- package/Utils/MetricUnitUtil.ts +34 -0
- package/Utils/Monitor/DeviceMacLearningUtil.ts +177 -0
- package/Utils/Monitor/MetricValueFormatter.ts +342 -0
- package/Utils/Monitor/MonitorTemplateCustomFieldUtil.ts +124 -0
- package/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.ts +7 -2
- package/Utils/Monitor/NetworkTopologyUtil.ts +693 -0
- package/Utils/NetworkAutomation/AutoImportRunChain.ts +138 -0
- package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
- package/Utils/Rum/ChunkMath.ts +106 -0
- package/Utils/Rum/SessionReplayHealth.ts +732 -0
- package/Utils/Rum/SessionReplayStringMap.ts +226 -0
- package/Utils/Schema/ModelSchema.ts +1 -0
- package/Utils/StatusPage/ResourceSearch.ts +290 -0
- package/Utils/Telemetry/OriginAllowList.ts +355 -0
- package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
- package/Utils/ValueFormatter.ts +35 -1
- package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
- package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
- package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
- package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +12 -12
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/InventoryItem.js +34 -1
- package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -1
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +128 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
- package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
- package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
- package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
- package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +769 -109
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
- package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
- package/build/dist/Server/API/UserTelegramAPI.js +28 -6
- package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +73 -14
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +19 -7
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Infrastructure/Redis.js +8 -8
- package/build/dist/Server/Infrastructure/Redis.js.map +1 -1
- package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Infrastructure/Status.js +10 -4
- package/build/dist/Server/Infrastructure/Status.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +315 -8
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AccessTokenService.js +1 -0
- package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
- package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
- package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +34 -0
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
- package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseService.js +58 -13
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/GlobalConfigService.js +133 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
- package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +32 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemService.js +28 -1
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
- package/build/dist/Server/Services/MetricService.js +163 -0
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +29 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +116 -17
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +349 -64
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +65 -0
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +54 -0
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +22 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
- package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
- package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
- package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
- package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +62 -2
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TeamPermissionService.js +166 -3
- package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +60 -25
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationSettingService.js +26 -6
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserTelegramService.js +257 -4
- package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +29 -4
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryUtil.js +36 -0
- package/build/dist/Server/Types/Database/QueryUtil.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +75 -0
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
- package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
- package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +53 -18
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +38 -5
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +54 -3
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +2 -2
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -1
- package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
- package/build/dist/Server/Utils/LogRedaction.js +20 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Logger.js +10 -0
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +323 -81
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +29 -5
- package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +254 -48
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +58 -9
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js +9 -3
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js +26 -12
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +74 -33
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +22 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.js +114 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +25 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
- package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
- package/build/dist/Server/Utils/SSRFProtection.js +136 -9
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +3 -14
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
- package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +9 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
- package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +70 -13
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
- package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Types/BaseDatabase/IncludesAnyOfGroups.js +54 -0
- package/build/dist/Types/BaseDatabase/IncludesAnyOfGroups.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
- package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
- package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardVariable.js +1 -0
- package/build/dist/Types/Dashboard/DashboardVariable.js.map +1 -1
- package/build/dist/Types/Icon/IconProp.js +1 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/JSON.js +1 -0
- package/build/dist/Types/JSON.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +131 -37
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
- package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
- package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
- package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
- package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
- package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
- package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
- package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
- package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
- package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
- package/build/dist/Types/NetworkAutomation/RuleRunResult.js +291 -6
- package/build/dist/Types/NetworkAutomation/RuleRunResult.js.map +1 -1
- package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
- package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplay.js +117 -0
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
- package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
- package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
- package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
- package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
- package/build/dist/Types/SerializableObjectDictionary.js +4 -0
- package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
- package/build/dist/Types/Telemetry/InventoryLiveness.js +37 -0
- package/build/dist/Types/Telemetry/InventoryLiveness.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
- package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
- package/build/dist/Types/WebsiteRequest.js +55 -3
- package/build/dist/Types/WebsiteRequest.js.map +1 -1
- package/build/dist/UI/Components/CSVFileUpload/CSVFileUpload.js +7 -0
- package/build/dist/UI/Components/CSVFileUpload/CSVFileUpload.js.map +1 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +89 -8
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
- package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
- package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js +137 -0
- package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js.map +1 -0
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
- package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
- package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
- package/build/dist/UI/Components/Header/Header.js +2 -3
- package/build/dist/UI/Components/Header/Header.js.map +1 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
- package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
- package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
- package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
- package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
- package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +5 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
- package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
- package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
- package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
- package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
- package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
- package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +38 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
- package/build/dist/UI/Components/Table/CellClassName.js +55 -0
- package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
- package/build/dist/UI/Components/Table/TableRow.js +16 -13
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
- package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
- package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
- package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Config.js +10 -20
- package/build/dist/UI/Config.js.map +1 -1
- package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
- package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
- package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
- package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Utils/API.js +67 -5
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardMonitorListComponent.js +9 -1
- package/build/dist/Utils/Dashboard/Components/DashboardMonitorListComponent.js.map +1 -1
- package/build/dist/Utils/Dashboard/LabelVariable.js +96 -0
- package/build/dist/Utils/Dashboard/LabelVariable.js.map +1 -0
- package/build/dist/Utils/Dashboard/VariableUrlState.js +19 -4
- package/build/dist/Utils/Dashboard/VariableUrlState.js.map +1 -1
- package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
- package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
- package/build/dist/Utils/MetricUnitUtil.js +26 -0
- package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
- package/build/dist/Utils/Monitor/DeviceMacLearningUtil.js +112 -0
- package/build/dist/Utils/Monitor/DeviceMacLearningUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MetricValueFormatter.js +276 -0
- package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorTemplateCustomFieldUtil.js +101 -0
- package/build/dist/Utils/Monitor/MonitorTemplateCustomFieldUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js +7 -2
- package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +484 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkAutomation/AutoImportRunChain.js +59 -0
- package/build/dist/Utils/NetworkAutomation/AutoImportRunChain.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
- package/build/dist/Utils/Rum/ChunkMath.js +76 -0
- package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
- package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
- package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
- package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js +1 -0
- package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
- package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
- package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
- package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
- package/build/dist/Utils/ValueFormatter.js +32 -1
- package/build/dist/Utils/ValueFormatter.js.map +1 -1
- package/jest.config.json +2 -0
- package/package.json +1 -1
- package/test-setup.sh +9 -9
- package/tsconfig.json +51 -11
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import CapturedMetric from "../../../Types/Monitor/CustomCodeMonitor/CapturedMetric";
|
|
2
2
|
import ReturnResult from "../../../Types/IsolatedVM/ReturnResult";
|
|
3
3
|
import { JSONObject } from "../../../Types/JSON";
|
|
4
|
-
import
|
|
4
|
+
import HTTPResponseBodyReader, {
|
|
5
|
+
HTTPResponseBodyBudget,
|
|
6
|
+
} from "../../../Utils/HTTPResponseBodyReader";
|
|
7
|
+
import axios, { AxiosError, AxiosResponse } from "axios";
|
|
5
8
|
import crypto from "crypto";
|
|
6
9
|
import http from "http";
|
|
7
10
|
import https from "https";
|
|
8
11
|
import ivm from "isolated-vm";
|
|
9
|
-
import
|
|
12
|
+
import DataSourceEgressGuard, {
|
|
13
|
+
EgressLookupFunction,
|
|
14
|
+
} from "../DataSource/EgressGuard";
|
|
10
15
|
import SSRFProtection from "../SSRFProtection";
|
|
16
|
+
import CaptureSpan from "../Telemetry/CaptureSpan";
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
* How often to wake Node's event loop while sandboxed code is running. See
|
|
20
|
+
* the comment on hostBridgeTicker in runCodeInSandbox: the isolate's host
|
|
21
|
+
* bridges only advance on an event-loop turn, and a loop with nothing else
|
|
22
|
+
* pending sleeps until its next timer. 5ms is small against any real host
|
|
23
|
+
* operation and costs one empty callback per tick.
|
|
24
|
+
*/
|
|
25
|
+
const HOST_BRIDGE_TICK_MS: number = 5;
|
|
11
26
|
|
|
12
27
|
export default class VMRunner {
|
|
13
28
|
/*
|
|
@@ -22,37 +37,53 @@ export default class VMRunner {
|
|
|
22
37
|
*/
|
|
23
38
|
private static resolveEffectiveRequestUrl(data: {
|
|
24
39
|
method: string;
|
|
25
|
-
url
|
|
40
|
+
url?: string | undefined;
|
|
26
41
|
config?: JSONObject | undefined;
|
|
27
42
|
}): string {
|
|
28
|
-
const baseUrl:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
const baseUrl: unknown = data.config?.["baseURL"];
|
|
44
|
+
const requestedUrl: unknown =
|
|
45
|
+
data.method === "request" ? data.config?.["url"] : data.url;
|
|
46
|
+
const allowAbsoluteUrls: unknown = data.config?.["allowAbsoluteUrls"];
|
|
47
|
+
const axiosAbsoluteUrlPattern: RegExp = new RegExp(
|
|
48
|
+
"^([a-z][a-z\\d+\\-.]*:)?//",
|
|
49
|
+
"i",
|
|
50
|
+
);
|
|
51
|
+
const httpUrlPattern: RegExp = new RegExp("^https?://", "i");
|
|
52
|
+
|
|
53
|
+
/*
|
|
54
|
+
* Mirror Axios's buildFullPath/isAbsoluteURL decision exactly before the
|
|
55
|
+
* SSRF guard sees the target. In particular, protocol-relative URLs and
|
|
56
|
+
* every RFC 3986 scheme count as absolute to Axios, while
|
|
57
|
+
* allowAbsoluteUrls:false deliberately combines even an absolute URL with
|
|
58
|
+
* baseURL. Direct-method positional URLs remain authoritative when they
|
|
59
|
+
* are the empty string; config.url must not silently replace them.
|
|
60
|
+
*/
|
|
61
|
+
const isAxiosAbsoluteUrl: boolean =
|
|
62
|
+
typeof requestedUrl === "string" &&
|
|
63
|
+
axiosAbsoluteUrlPattern.test(requestedUrl);
|
|
64
|
+
let effectiveUrl: unknown = requestedUrl;
|
|
65
|
+
|
|
66
|
+
if (baseUrl && (!isAxiosAbsoluteUrl || allowAbsoluteUrls === false)) {
|
|
67
|
+
if (typeof baseUrl !== "string") {
|
|
46
68
|
throw new Error("Request URL must be an absolute http or https URL.");
|
|
47
69
|
}
|
|
48
|
-
|
|
70
|
+
|
|
71
|
+
effectiveUrl = requestedUrl
|
|
72
|
+
? `${baseUrl.replace(/\/?\/$/, "")}/${String(requestedUrl).replace(
|
|
73
|
+
/^\/+/,
|
|
74
|
+
"",
|
|
75
|
+
)}`
|
|
76
|
+
: baseUrl;
|
|
49
77
|
}
|
|
50
78
|
|
|
51
|
-
if (
|
|
79
|
+
if (
|
|
80
|
+
typeof effectiveUrl !== "string" ||
|
|
81
|
+
!httpUrlPattern.test(effectiveUrl)
|
|
82
|
+
) {
|
|
52
83
|
throw new Error("Request URL must be an absolute http or https URL.");
|
|
53
84
|
}
|
|
54
85
|
|
|
55
|
-
return
|
|
86
|
+
return effectiveUrl;
|
|
56
87
|
}
|
|
57
88
|
|
|
58
89
|
@CaptureSpan()
|
|
@@ -71,6 +102,15 @@ export default class VMRunner {
|
|
|
71
102
|
* strict policy, which is what a caller that says nothing should get.
|
|
72
103
|
*/
|
|
73
104
|
allowPrivateNetworkRequests?: boolean | undefined;
|
|
105
|
+
/*
|
|
106
|
+
* A trusted caller's already-resolved egress policy. This is separate
|
|
107
|
+
* from eligibility above because the workflow caller uses the API
|
|
108
|
+
* server's webhook configuration, while the Probe has already resolved
|
|
109
|
+
* its own local setting. When supplied, it is authoritative and the API
|
|
110
|
+
* server's webhook policy is not consulted. Absent leaves the workflow
|
|
111
|
+
* caller's webhook behavior unchanged.
|
|
112
|
+
*/
|
|
113
|
+
privateNetworkAccessIsAllowed?: boolean | undefined;
|
|
74
114
|
/*
|
|
75
115
|
* Overrides the sentence a private-tier refusal appends, telling the
|
|
76
116
|
* operator which setting would permit it. Whoever runs this sandbox
|
|
@@ -88,7 +128,17 @@ export default class VMRunner {
|
|
|
88
128
|
const MAX_LOG_MESSAGES: number = 1000;
|
|
89
129
|
const MAX_LOG_BYTES: number = 1_000_000;
|
|
90
130
|
const MAX_SCRIPT_ERROR_MESSAGE_LENGTH: number = 10_000;
|
|
131
|
+
const MAX_HTTP_RESPONSE_BYTES: number = 10 * 1024 * 1024;
|
|
132
|
+
const MAX_HTTP_REQUEST_BYTES: number = 10 * 1024 * 1024;
|
|
133
|
+
const MAX_HTTP_CONFIG_BYTES: number = 256 * 1024;
|
|
134
|
+
const MAX_HTTP_URL_BYTES: number = 16 * 1024;
|
|
135
|
+
const MAX_BASE64_RESPONSE_SOURCE_BYTES: number = Math.floor(
|
|
136
|
+
((MAX_HTTP_RESPONSE_BYTES - 64 * 1024) * 3) / 4,
|
|
137
|
+
);
|
|
91
138
|
let logBytes: number = 0;
|
|
139
|
+
let serializedHttpRequestBytes: number = 0;
|
|
140
|
+
const httpResponseBodyBudget: HTTPResponseBodyBudget =
|
|
141
|
+
new HTTPResponseBodyBudget(MAX_HTTP_RESPONSE_BYTES);
|
|
92
142
|
|
|
93
143
|
const pendingHostTimeouts: Set<ReturnType<typeof global.setTimeout>> =
|
|
94
144
|
new Set<ReturnType<typeof global.setTimeout>>();
|
|
@@ -342,13 +392,13 @@ export default class VMRunner {
|
|
|
342
392
|
const executeAxiosRequest: (
|
|
343
393
|
signal: AbortSignal,
|
|
344
394
|
method: string,
|
|
345
|
-
url
|
|
395
|
+
url?: string,
|
|
346
396
|
arg1?: string,
|
|
347
397
|
arg2?: string,
|
|
348
398
|
) => Promise<string> = async (
|
|
349
399
|
signal: AbortSignal,
|
|
350
400
|
method: string,
|
|
351
|
-
url
|
|
401
|
+
url?: string,
|
|
352
402
|
arg1?: string,
|
|
353
403
|
arg2?: string,
|
|
354
404
|
): Promise<string> => {
|
|
@@ -367,32 +417,82 @@ export default class VMRunner {
|
|
|
367
417
|
? (JSON.parse(configStr) as JSONObject)
|
|
368
418
|
: undefined;
|
|
369
419
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
] as JSONObject | undefined;
|
|
420
|
+
if (method === "request" && config) {
|
|
421
|
+
const requestBody: unknown = config["data"];
|
|
422
|
+
const configWithoutBody: JSONObject = { ...config };
|
|
423
|
+
delete configWithoutBody["data"];
|
|
375
424
|
|
|
376
425
|
if (
|
|
377
|
-
|
|
378
|
-
|
|
426
|
+
Buffer.byteLength(JSON.stringify(requestBody) || "", "utf8") >
|
|
427
|
+
MAX_HTTP_REQUEST_BYTES
|
|
379
428
|
) {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
429
|
+
throw new Error("HTTP request body exceeded the allowed size.");
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (
|
|
433
|
+
Buffer.byteLength(JSON.stringify(configWithoutBody), "utf8") >
|
|
434
|
+
MAX_HTTP_CONFIG_BYTES
|
|
435
|
+
) {
|
|
436
|
+
throw new Error("HTTP request config exceeded the allowed size.");
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
let suppliedHttpsAgentOptions: https.AgentOptions = {};
|
|
441
|
+
|
|
442
|
+
const pickAgentOptions: (
|
|
443
|
+
source: JSONObject | undefined,
|
|
444
|
+
allowedKeys: Array<string>,
|
|
445
|
+
) => Record<string, unknown> = (
|
|
446
|
+
source: JSONObject | undefined,
|
|
447
|
+
allowedKeys: Array<string>,
|
|
448
|
+
): Record<string, unknown> => {
|
|
449
|
+
const picked: Record<string, unknown> = {};
|
|
450
|
+
if (!source) {
|
|
451
|
+
return picked;
|
|
383
452
|
}
|
|
384
453
|
|
|
385
|
-
const
|
|
386
|
-
|
|
454
|
+
for (const key of allowedKeys) {
|
|
455
|
+
if (source[key] !== undefined) {
|
|
456
|
+
picked[key] = source[key];
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
return picked;
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
/*
|
|
464
|
+
* Preserve only TLS semantics from a serialized HTTPS Agent. Network
|
|
465
|
+
* and pooling options are intentionally discarded: host/port/path and
|
|
466
|
+
* custom socket hooks can steer around the validated URL, while a
|
|
467
|
+
* per-request keep-alive agent would leave an idle socket behind.
|
|
468
|
+
*/
|
|
469
|
+
if (config) {
|
|
470
|
+
const httpsAgentConfig: JSONObject | undefined = config[
|
|
471
|
+
"httpsAgent"
|
|
387
472
|
] as JSONObject | undefined;
|
|
388
473
|
|
|
389
474
|
if (
|
|
390
|
-
|
|
391
|
-
|
|
475
|
+
httpsAgentConfig &&
|
|
476
|
+
httpsAgentConfig["__agentType"] === "__https_agent__"
|
|
392
477
|
) {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
478
|
+
suppliedHttpsAgentOptions = pickAgentOptions(
|
|
479
|
+
httpsAgentConfig["options"] as JSONObject | undefined,
|
|
480
|
+
[
|
|
481
|
+
"rejectUnauthorized",
|
|
482
|
+
"ca",
|
|
483
|
+
"cert",
|
|
484
|
+
"key",
|
|
485
|
+
"pfx",
|
|
486
|
+
"passphrase",
|
|
487
|
+
"ciphers",
|
|
488
|
+
"minVersion",
|
|
489
|
+
"maxVersion",
|
|
490
|
+
"secureProtocol",
|
|
491
|
+
"honorCipherOrder",
|
|
492
|
+
"ALPNProtocols",
|
|
493
|
+
"servername",
|
|
494
|
+
],
|
|
495
|
+
) as https.AgentOptions;
|
|
396
496
|
}
|
|
397
497
|
}
|
|
398
498
|
|
|
@@ -435,9 +535,12 @@ export default class VMRunner {
|
|
|
435
535
|
config,
|
|
436
536
|
});
|
|
437
537
|
|
|
438
|
-
|
|
538
|
+
const validatedTarget: Awaited<
|
|
539
|
+
ReturnType<typeof SSRFProtection.validateAndResolveWebhookTarget>
|
|
540
|
+
> = await SSRFProtection.validateAndResolveWebhookTarget(effectiveUrl, {
|
|
439
541
|
allowPrivateNetworkTargets:
|
|
440
542
|
options.allowPrivateNetworkRequests === true,
|
|
543
|
+
privateNetworkAccessIsAllowed: options.privateNetworkAccessIsAllowed,
|
|
441
544
|
/*
|
|
442
545
|
* "Webhook URL" is wrong here in both directions: sandboxed code
|
|
443
546
|
* requests whatever it likes, and one of this runner's two callers
|
|
@@ -446,23 +549,103 @@ export default class VMRunner {
|
|
|
446
549
|
targetLabel: "Request URL",
|
|
447
550
|
privateNetworkHint: options.privateNetworkHint,
|
|
448
551
|
});
|
|
552
|
+
const canonicalUrl: string = validatedTarget.url.toString();
|
|
553
|
+
const pinnedLookup: EgressLookupFunction =
|
|
554
|
+
DataSourceEgressGuard.createPinnedLookup(validatedTarget.addresses);
|
|
449
555
|
|
|
450
556
|
/*
|
|
451
|
-
* The URL that was just validated has to be the URL that
|
|
452
|
-
* dialled. Each of these would otherwise steer the connection
|
|
557
|
+
* The canonical URL that was just validated has to be the URL that
|
|
558
|
+
* gets dialled. Each of these would otherwise steer the connection
|
|
453
559
|
* somewhere else entirely, past the check above:
|
|
454
|
-
* proxy - sends the request to an arbitrary host:port
|
|
560
|
+
* proxy - sends the request to an arbitrary host:port; setting
|
|
561
|
+
* it false also disables Axios's environment proxies
|
|
455
562
|
* socketPath - connects to a unix socket (/var/run/docker.sock)
|
|
456
563
|
* transport / adapter - replaces the transport wholesale
|
|
564
|
+
* HTTP/2 - uses Axios's shared session pool instead of these agents
|
|
565
|
+
* lookup - takes precedence over the pinned Agent lookup
|
|
566
|
+
* baseURL / config.url / allowAbsoluteUrls - reinterpret the URL
|
|
457
567
|
* and a redirect would let a validated public host nominate an
|
|
458
|
-
* internal one on the second hop.
|
|
568
|
+
* internal one on the second hop. The pinned lookup closes the DNS
|
|
569
|
+
* rebinding window between policy validation and socket creation.
|
|
459
570
|
*/
|
|
460
|
-
const safeConfig: JSONObject = config || {};
|
|
461
|
-
delete safeConfig["proxy"];
|
|
571
|
+
const safeConfig: JSONObject = { ...(config || {}) };
|
|
462
572
|
delete safeConfig["socketPath"];
|
|
463
573
|
delete safeConfig["transport"];
|
|
464
574
|
delete safeConfig["adapter"];
|
|
575
|
+
delete safeConfig["http2Options"];
|
|
576
|
+
delete safeConfig["lookup"];
|
|
577
|
+
delete safeConfig["baseURL"];
|
|
578
|
+
delete safeConfig["url"];
|
|
579
|
+
delete safeConfig["allowAbsoluteUrls"];
|
|
580
|
+
safeConfig["proxy"] = false;
|
|
465
581
|
safeConfig["maxRedirects"] = 0;
|
|
582
|
+
safeConfig["httpVersion"] = 1;
|
|
583
|
+
|
|
584
|
+
const getEffectiveByteLimit: (
|
|
585
|
+
configuredLimit: unknown,
|
|
586
|
+
securityLimit: number,
|
|
587
|
+
) => number = (
|
|
588
|
+
configuredLimit: unknown,
|
|
589
|
+
securityLimit: number,
|
|
590
|
+
): number => {
|
|
591
|
+
if (
|
|
592
|
+
typeof configuredLimit === "number" &&
|
|
593
|
+
Number.isFinite(configuredLimit) &&
|
|
594
|
+
configuredLimit >= 0
|
|
595
|
+
) {
|
|
596
|
+
return Math.min(Math.floor(configuredLimit), securityLimit);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
return securityLimit;
|
|
600
|
+
};
|
|
601
|
+
const effectiveMaxContentLength: number = getEffectiveByteLimit(
|
|
602
|
+
config?.["maxContentLength"],
|
|
603
|
+
MAX_HTTP_RESPONSE_BYTES,
|
|
604
|
+
);
|
|
605
|
+
const effectiveMaxBodyLength: number = getEffectiveByteLimit(
|
|
606
|
+
config?.["maxBodyLength"],
|
|
607
|
+
MAX_HTTP_REQUEST_BYTES,
|
|
608
|
+
);
|
|
609
|
+
/*
|
|
610
|
+
* The reader below is the sole response cap so every crossed byte is
|
|
611
|
+
* charged to the execution-wide budget before a rejection.
|
|
612
|
+
*/
|
|
613
|
+
safeConfig["maxContentLength"] = -1;
|
|
614
|
+
safeConfig["maxBodyLength"] = effectiveMaxBodyLength;
|
|
615
|
+
const requestedResponseType: string | undefined =
|
|
616
|
+
typeof safeConfig["responseType"] === "string"
|
|
617
|
+
? (safeConfig["responseType"] as string)
|
|
618
|
+
: undefined;
|
|
619
|
+
const requestedResponseEncoding: string | undefined =
|
|
620
|
+
typeof safeConfig["responseEncoding"] === "string"
|
|
621
|
+
? (safeConfig["responseEncoding"] as string)
|
|
622
|
+
: undefined;
|
|
623
|
+
const transitionalConfig: JSONObject | undefined =
|
|
624
|
+
safeConfig["transitional"] &&
|
|
625
|
+
typeof safeConfig["transitional"] === "object"
|
|
626
|
+
? (safeConfig["transitional"] as JSONObject)
|
|
627
|
+
: undefined;
|
|
628
|
+
const forcedJsonParsing: boolean =
|
|
629
|
+
typeof transitionalConfig?.["forcedJSONParsing"] === "boolean"
|
|
630
|
+
? (transitionalConfig["forcedJSONParsing"] as boolean)
|
|
631
|
+
: true;
|
|
632
|
+
const silentJsonParsing: boolean =
|
|
633
|
+
typeof transitionalConfig?.["silentJSONParsing"] === "boolean"
|
|
634
|
+
? (transitionalConfig["silentJSONParsing"] as boolean)
|
|
635
|
+
: true;
|
|
636
|
+
const shouldParseResponseAsJson: boolean =
|
|
637
|
+
requestedResponseType === "json" ||
|
|
638
|
+
(forcedJsonParsing && !requestedResponseType);
|
|
639
|
+
const strictJsonParsing: boolean =
|
|
640
|
+
requestedResponseType === "json" && !silentJsonParsing;
|
|
641
|
+
safeConfig["responseType"] = "stream";
|
|
642
|
+
safeConfig["httpAgent"] = new http.Agent({
|
|
643
|
+
lookup: pinnedLookup as never,
|
|
644
|
+
}) as unknown as JSONObject;
|
|
645
|
+
safeConfig["httpsAgent"] = new https.Agent({
|
|
646
|
+
...suppliedHttpsAgentOptions,
|
|
647
|
+
lookup: pinnedLookup as never,
|
|
648
|
+
}) as unknown as JSONObject;
|
|
466
649
|
Object.defineProperty(safeConfig, "signal", {
|
|
467
650
|
value: signal,
|
|
468
651
|
enumerable: true,
|
|
@@ -470,51 +653,258 @@ export default class VMRunner {
|
|
|
470
653
|
});
|
|
471
654
|
config = safeConfig;
|
|
472
655
|
|
|
656
|
+
interface NormalizedResponseData {
|
|
657
|
+
data: string;
|
|
658
|
+
encoding:
|
|
659
|
+
| "base64-arraybuffer"
|
|
660
|
+
| "base64-json-or-text"
|
|
661
|
+
| "base64-text";
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
const responseDataEncoding:
|
|
665
|
+
| "base64-arraybuffer"
|
|
666
|
+
| "base64-json-or-text"
|
|
667
|
+
| "base64-text" =
|
|
668
|
+
requestedResponseType === "arraybuffer"
|
|
669
|
+
? "base64-arraybuffer"
|
|
670
|
+
: shouldParseResponseAsJson
|
|
671
|
+
? "base64-json-or-text"
|
|
672
|
+
: "base64-text";
|
|
673
|
+
|
|
674
|
+
const serializedResponseConfig: Record<string, unknown> = {
|
|
675
|
+
method:
|
|
676
|
+
method === "request"
|
|
677
|
+
? String(safeConfig["method"] || "get").toLowerCase()
|
|
678
|
+
: method,
|
|
679
|
+
url: canonicalUrl,
|
|
680
|
+
maxContentLength: effectiveMaxContentLength,
|
|
681
|
+
maxBodyLength: effectiveMaxBodyLength,
|
|
682
|
+
};
|
|
683
|
+
if (requestedResponseType !== undefined) {
|
|
684
|
+
serializedResponseConfig["responseType"] = requestedResponseType;
|
|
685
|
+
}
|
|
686
|
+
if (requestedResponseEncoding !== undefined) {
|
|
687
|
+
serializedResponseConfig["responseEncoding"] =
|
|
688
|
+
requestedResponseEncoding;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
const encodeResponseBody: (body: Buffer) => NormalizedResponseData = (
|
|
692
|
+
body: Buffer,
|
|
693
|
+
): NormalizedResponseData => {
|
|
694
|
+
if (body.length > MAX_BASE64_RESPONSE_SOURCE_BYTES) {
|
|
695
|
+
throw new Error(
|
|
696
|
+
"Remote response exceeded the allowed serialized size.",
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
return {
|
|
701
|
+
data: body.toString("base64"),
|
|
702
|
+
encoding: responseDataEncoding,
|
|
703
|
+
};
|
|
704
|
+
};
|
|
705
|
+
|
|
706
|
+
type ResponseBodyReadAxiosError = AxiosError & {
|
|
707
|
+
__oneuptimeResponseBodyReadFailed: true;
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
const wrapResponseBodyReadError: (
|
|
711
|
+
error: unknown,
|
|
712
|
+
response: AxiosResponse,
|
|
713
|
+
) => ResponseBodyReadAxiosError = (
|
|
714
|
+
error: unknown,
|
|
715
|
+
response: AxiosResponse,
|
|
716
|
+
): ResponseBodyReadAxiosError => {
|
|
717
|
+
const wrappedError: AxiosError = AxiosError.from(
|
|
718
|
+
error,
|
|
719
|
+
AxiosError.ERR_BAD_RESPONSE,
|
|
720
|
+
response.config,
|
|
721
|
+
response.request,
|
|
722
|
+
response,
|
|
723
|
+
{ __oneuptimeResponseBodyReadFailed: true },
|
|
724
|
+
);
|
|
725
|
+
|
|
726
|
+
/*
|
|
727
|
+
* Axios's streamed maxContentLength wrapper can throw an AxiosError
|
|
728
|
+
* before attaching its response. Restore the association here so
|
|
729
|
+
* interceptors and catch handlers retain status, headers, config,
|
|
730
|
+
* and request context just as they do for buffered responses.
|
|
731
|
+
*/
|
|
732
|
+
wrappedError.response = response;
|
|
733
|
+
wrappedError.config = response.config;
|
|
734
|
+
wrappedError.request = response.request;
|
|
735
|
+
|
|
736
|
+
return wrappedError as ResponseBodyReadAxiosError;
|
|
737
|
+
};
|
|
738
|
+
|
|
739
|
+
const normalizeResponseData: (
|
|
740
|
+
response: AxiosResponse,
|
|
741
|
+
) => Promise<NormalizedResponseData> = async (
|
|
742
|
+
response: AxiosResponse,
|
|
743
|
+
): Promise<NormalizedResponseData> => {
|
|
744
|
+
const responseData: unknown = response.data;
|
|
745
|
+
const isStream: boolean = Boolean(
|
|
746
|
+
responseData &&
|
|
747
|
+
typeof responseData === "object" &&
|
|
748
|
+
typeof (responseData as Partial<AsyncIterable<unknown>>)[
|
|
749
|
+
Symbol.asyncIterator
|
|
750
|
+
] === "function",
|
|
751
|
+
);
|
|
752
|
+
|
|
753
|
+
if (!isStream) {
|
|
754
|
+
/*
|
|
755
|
+
* Test adapters can return an already-decoded value. Convert that
|
|
756
|
+
* value back to bounded bytes so every path uses the same base64
|
|
757
|
+
* bridge and none can trigger host-side JSON escaping or Buffer's
|
|
758
|
+
* decimal-array serialization.
|
|
759
|
+
*/
|
|
760
|
+
let body: Buffer;
|
|
761
|
+
|
|
762
|
+
if (Buffer.isBuffer(responseData)) {
|
|
763
|
+
body = responseData;
|
|
764
|
+
} else if (ArrayBuffer.isView(responseData)) {
|
|
765
|
+
body = Buffer.from(
|
|
766
|
+
responseData.buffer,
|
|
767
|
+
responseData.byteOffset,
|
|
768
|
+
responseData.byteLength,
|
|
769
|
+
);
|
|
770
|
+
} else if (responseData instanceof ArrayBuffer) {
|
|
771
|
+
body = Buffer.from(responseData);
|
|
772
|
+
} else {
|
|
773
|
+
const serialized: string =
|
|
774
|
+
typeof responseData === "string"
|
|
775
|
+
? responseData
|
|
776
|
+
: JSON.stringify(responseData ?? "");
|
|
777
|
+
body = Buffer.from(serialized, "utf8");
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
try {
|
|
781
|
+
httpResponseBodyBudget.consume(body.length);
|
|
782
|
+
return encodeResponseBody(body);
|
|
783
|
+
} catch (error: unknown) {
|
|
784
|
+
throw wrapResponseBodyReadError(error, response);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
let body: Buffer;
|
|
789
|
+
try {
|
|
790
|
+
body = await HTTPResponseBodyReader.read(responseData, {
|
|
791
|
+
budget: httpResponseBodyBudget,
|
|
792
|
+
statusCode: response.status,
|
|
793
|
+
headers: response.headers,
|
|
794
|
+
limitRedirectResponseBody: false,
|
|
795
|
+
isHeadResponse:
|
|
796
|
+
method === "head" ||
|
|
797
|
+
(method === "request" &&
|
|
798
|
+
String(safeConfig["method"] || "").toLowerCase() === "head"),
|
|
799
|
+
maximumResponseBytes: effectiveMaxContentLength,
|
|
800
|
+
});
|
|
801
|
+
} catch (error: unknown) {
|
|
802
|
+
throw wrapResponseBodyReadError(error, response);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/*
|
|
806
|
+
* Never put raw bytes or decoded attacker text directly into the
|
|
807
|
+
* host-side JSON envelope. Buffer.toJSON creates a decimal array,
|
|
808
|
+
* while JSON escaping can turn one control byte into six characters;
|
|
809
|
+
* either form multiplies memory outside the isolate. Base64 has a
|
|
810
|
+
* fixed 4/3 expansion. The reserved 64 KiB covers status/headers and
|
|
811
|
+
* wrapper fields, keeping the complete bridge string under 10 MiB.
|
|
812
|
+
* Decoding and best-effort JSON parsing happen inside the isolate's
|
|
813
|
+
* 128 MiB memory limit.
|
|
814
|
+
*/
|
|
815
|
+
try {
|
|
816
|
+
return encodeResponseBody(body);
|
|
817
|
+
} catch (error: unknown) {
|
|
818
|
+
throw wrapResponseBodyReadError(error, response);
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
|
|
822
|
+
const serializeResponseEnvelope: (
|
|
823
|
+
metadata: Record<string, unknown>,
|
|
824
|
+
responseData: NormalizedResponseData,
|
|
825
|
+
) => string = (
|
|
826
|
+
metadata: Record<string, unknown>,
|
|
827
|
+
responseData: NormalizedResponseData,
|
|
828
|
+
): string => {
|
|
829
|
+
/*
|
|
830
|
+
* Keep the attacker-controlled body outside the JSON metadata.
|
|
831
|
+
* Parsing a JSON object that contains a near-limit base64 string
|
|
832
|
+
* otherwise allocates a second full copy inside the isolate. A JSON
|
|
833
|
+
* line followed by base64 is unambiguous because JSON escapes any
|
|
834
|
+
* newline found in metadata values.
|
|
835
|
+
*/
|
|
836
|
+
const envelope: string = `${JSON.stringify({
|
|
837
|
+
...metadata,
|
|
838
|
+
__oneuptimeDataEncoding: responseData.encoding,
|
|
839
|
+
__oneuptimeResponseEncoding: requestedResponseEncoding,
|
|
840
|
+
__oneuptimeShouldParseJson: shouldParseResponseAsJson,
|
|
841
|
+
__oneuptimeStrictJsonParsing: strictJsonParsing,
|
|
842
|
+
__oneuptimeConfig: serializedResponseConfig,
|
|
843
|
+
__oneuptimeHasRequest: true,
|
|
844
|
+
})}\n${responseData.data}`;
|
|
845
|
+
|
|
846
|
+
if (Buffer.byteLength(envelope, "utf8") > MAX_HTTP_RESPONSE_BYTES) {
|
|
847
|
+
throw new Error(
|
|
848
|
+
"Remote response exceeded the allowed serialized size.",
|
|
849
|
+
);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
return envelope;
|
|
853
|
+
};
|
|
854
|
+
|
|
473
855
|
try {
|
|
474
856
|
let response: AxiosResponse;
|
|
475
857
|
|
|
476
858
|
switch (method) {
|
|
477
859
|
case "get":
|
|
478
|
-
response = await axios.get(
|
|
860
|
+
response = await axios.get(canonicalUrl, config);
|
|
479
861
|
break;
|
|
480
862
|
case "head":
|
|
481
|
-
response = await axios.head(
|
|
863
|
+
response = await axios.head(canonicalUrl, config);
|
|
482
864
|
break;
|
|
483
865
|
case "options":
|
|
484
|
-
response = await axios.options(
|
|
866
|
+
response = await axios.options(canonicalUrl, config);
|
|
485
867
|
break;
|
|
486
868
|
case "post":
|
|
487
|
-
response = await axios.post(
|
|
869
|
+
response = await axios.post(canonicalUrl, body, config);
|
|
488
870
|
break;
|
|
489
871
|
case "put":
|
|
490
|
-
response = await axios.put(
|
|
872
|
+
response = await axios.put(canonicalUrl, body, config);
|
|
491
873
|
break;
|
|
492
874
|
case "patch":
|
|
493
|
-
response = await axios.patch(
|
|
875
|
+
response = await axios.patch(canonicalUrl, body, config);
|
|
494
876
|
break;
|
|
495
877
|
case "delete":
|
|
496
|
-
response = await axios.delete(
|
|
878
|
+
response = await axios.delete(canonicalUrl, config);
|
|
497
879
|
break;
|
|
498
|
-
case "request":
|
|
880
|
+
case "request": {
|
|
881
|
+
config["url"] = canonicalUrl;
|
|
499
882
|
response = await axios.request(
|
|
500
883
|
config as Parameters<typeof axios.request>[0],
|
|
501
884
|
);
|
|
502
885
|
break;
|
|
886
|
+
}
|
|
503
887
|
default:
|
|
504
888
|
throw new Error(`Unsupported HTTP method: ${method}`);
|
|
505
889
|
}
|
|
506
890
|
|
|
891
|
+
const normalizedResponseData: NormalizedResponseData =
|
|
892
|
+
await normalizeResponseData(response);
|
|
893
|
+
|
|
507
894
|
/*
|
|
508
895
|
* Convert AxiosHeaders to a plain object before serializing.
|
|
509
896
|
* JSON.stringify calls AxiosHeaders.toJSON(key) with a truthy key,
|
|
510
897
|
* which makes it join array headers (like set-cookie) with commas.
|
|
511
898
|
* This produces invalid Cookie headers when user code forwards them.
|
|
512
899
|
*/
|
|
513
|
-
return
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
900
|
+
return serializeResponseEnvelope(
|
|
901
|
+
{
|
|
902
|
+
status: response.status,
|
|
903
|
+
statusText: response.statusText,
|
|
904
|
+
headers: toPlainHeaders(response.headers),
|
|
905
|
+
},
|
|
906
|
+
normalizedResponseData,
|
|
907
|
+
);
|
|
518
908
|
} catch (err: unknown) {
|
|
519
909
|
/*
|
|
520
910
|
* If this is an axios error with a response (4xx, 5xx, etc.),
|
|
@@ -525,21 +915,47 @@ export default class VMRunner {
|
|
|
525
915
|
isAxiosError?: boolean;
|
|
526
916
|
response?: AxiosResponse<any, any, Record<string, unknown>>;
|
|
527
917
|
message?: string;
|
|
918
|
+
code?: string;
|
|
919
|
+
name?: string;
|
|
920
|
+
__oneuptimeResponseBodyReadFailed?: boolean;
|
|
528
921
|
} = err as {
|
|
529
922
|
isAxiosError?: boolean;
|
|
530
923
|
response?: AxiosResponse;
|
|
531
924
|
message?: string;
|
|
925
|
+
code?: string;
|
|
926
|
+
name?: string;
|
|
927
|
+
__oneuptimeResponseBodyReadFailed?: boolean;
|
|
532
928
|
};
|
|
533
929
|
|
|
534
930
|
if (axiosErr.isAxiosError && axiosErr.response) {
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
931
|
+
let errorForEnvelope: typeof axiosErr = axiosErr;
|
|
932
|
+
let normalizedResponseData: NormalizedResponseData;
|
|
933
|
+
|
|
934
|
+
if (axiosErr.__oneuptimeResponseBodyReadFailed) {
|
|
935
|
+
normalizedResponseData = encodeResponseBody(Buffer.alloc(0));
|
|
936
|
+
} else {
|
|
937
|
+
try {
|
|
938
|
+
normalizedResponseData = await normalizeResponseData(
|
|
939
|
+
axiosErr.response,
|
|
940
|
+
);
|
|
941
|
+
} catch (responseReadError: unknown) {
|
|
942
|
+
errorForEnvelope = responseReadError as typeof axiosErr;
|
|
943
|
+
normalizedResponseData = encodeResponseBody(Buffer.alloc(0));
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
return serializeResponseEnvelope(
|
|
948
|
+
{
|
|
949
|
+
__isAxiosError: true,
|
|
950
|
+
message: errorForEnvelope.message || "Request failed",
|
|
951
|
+
code: errorForEnvelope.code,
|
|
952
|
+
name: errorForEnvelope.name,
|
|
953
|
+
status: axiosErr.response.status,
|
|
954
|
+
statusText: axiosErr.response.statusText,
|
|
955
|
+
headers: toPlainHeaders(axiosErr.response.headers),
|
|
956
|
+
},
|
|
957
|
+
normalizedResponseData,
|
|
958
|
+
);
|
|
543
959
|
}
|
|
544
960
|
|
|
545
961
|
throw err;
|
|
@@ -547,9 +963,14 @@ export default class VMRunner {
|
|
|
547
963
|
};
|
|
548
964
|
|
|
549
965
|
const axiosStartCallback: ivm.Callback<
|
|
550
|
-
(method: string, url
|
|
966
|
+
(method: string, url?: string, arg1?: string, arg2?: string) => string
|
|
551
967
|
> = new ivm.Callback(
|
|
552
|
-
(
|
|
968
|
+
(
|
|
969
|
+
method: string,
|
|
970
|
+
url?: string,
|
|
971
|
+
arg1?: string,
|
|
972
|
+
arg2?: string,
|
|
973
|
+
): string => {
|
|
553
974
|
const operationId: string = String(++nextAxiosOperationId);
|
|
554
975
|
|
|
555
976
|
if (!acceptingHostOperations) {
|
|
@@ -564,6 +985,58 @@ export default class VMRunner {
|
|
|
564
985
|
return operationId;
|
|
565
986
|
}
|
|
566
987
|
|
|
988
|
+
try {
|
|
989
|
+
const urlBytes: number = Buffer.byteLength(url || "", "utf8");
|
|
990
|
+
const arg1Bytes: number = Buffer.byteLength(arg1 || "", "utf8");
|
|
991
|
+
const arg2Bytes: number = Buffer.byteLength(arg2 || "", "utf8");
|
|
992
|
+
const hasBody: boolean = ["post", "put", "patch"].includes(method);
|
|
993
|
+
|
|
994
|
+
if (urlBytes > MAX_HTTP_URL_BYTES) {
|
|
995
|
+
throw new Error("HTTP request URL exceeded the allowed size.");
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
if (hasBody) {
|
|
999
|
+
if (arg1Bytes > MAX_HTTP_REQUEST_BYTES) {
|
|
1000
|
+
throw new Error("HTTP request body exceeded the allowed size.");
|
|
1001
|
+
}
|
|
1002
|
+
if (arg2Bytes > MAX_HTTP_CONFIG_BYTES) {
|
|
1003
|
+
throw new Error(
|
|
1004
|
+
"HTTP request config exceeded the allowed size.",
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
1007
|
+
} else if (method === "request") {
|
|
1008
|
+
if (arg1Bytes > MAX_HTTP_REQUEST_BYTES + MAX_HTTP_CONFIG_BYTES) {
|
|
1009
|
+
throw new Error("HTTP request data exceeded the allowed size.");
|
|
1010
|
+
}
|
|
1011
|
+
} else if (arg1Bytes > MAX_HTTP_CONFIG_BYTES) {
|
|
1012
|
+
throw new Error("HTTP request config exceeded the allowed size.");
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
const operationBytes: number = urlBytes + arg1Bytes + arg2Bytes;
|
|
1016
|
+
if (
|
|
1017
|
+
serializedHttpRequestBytes + operationBytes >
|
|
1018
|
+
MAX_HTTP_REQUEST_BYTES
|
|
1019
|
+
) {
|
|
1020
|
+
throw new Error(
|
|
1021
|
+
"Sandbox HTTP requests exceeded the allowed cumulative request size.",
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
/*
|
|
1026
|
+
* This budget is deliberately never replenished. Keeping a
|
|
1027
|
+
* per-execution total prevents many individually legal requests
|
|
1028
|
+
* from retaining close to the full limit while DNS or sockets are
|
|
1029
|
+
* pending outside the isolate's memory limit.
|
|
1030
|
+
*/
|
|
1031
|
+
serializedHttpRequestBytes += operationBytes;
|
|
1032
|
+
} catch (error: unknown) {
|
|
1033
|
+
pendingAxiosOperations.set(operationId, {
|
|
1034
|
+
status: "rejected",
|
|
1035
|
+
errorMessage: sanitizeScriptError(error).message,
|
|
1036
|
+
});
|
|
1037
|
+
return operationId;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
567
1040
|
pendingAxiosOperations.set(operationId, { status: "pending" });
|
|
568
1041
|
const abortController: AbortController = new AbortController();
|
|
569
1042
|
pendingAxiosControllers.add(abortController);
|
|
@@ -608,17 +1081,26 @@ export default class VMRunner {
|
|
|
608
1081
|
pendingAxiosOperations.get(operationId);
|
|
609
1082
|
|
|
610
1083
|
if (!operation) {
|
|
611
|
-
return JSON.stringify(
|
|
612
|
-
status: "rejected",
|
|
613
|
-
errorMessage: "HTTP request result is unavailable",
|
|
614
|
-
});
|
|
1084
|
+
return `E${JSON.stringify("HTTP request result is unavailable")}`;
|
|
615
1085
|
}
|
|
616
1086
|
|
|
617
|
-
if (operation.status
|
|
618
|
-
|
|
1087
|
+
if (operation.status === "pending") {
|
|
1088
|
+
return "P";
|
|
619
1089
|
}
|
|
620
1090
|
|
|
621
|
-
|
|
1091
|
+
pendingAxiosOperations.delete(operationId);
|
|
1092
|
+
|
|
1093
|
+
if (operation.status === "rejected") {
|
|
1094
|
+
return `E${JSON.stringify(operation.errorMessage)}`;
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
/*
|
|
1098
|
+
* The fulfilled value is already a bounded JSON envelope. Prefix
|
|
1099
|
+
* it instead of embedding it in another JSON document; otherwise
|
|
1100
|
+
* a response near the byte limit is copied and escaped a second
|
|
1101
|
+
* time while crossing into the isolate.
|
|
1102
|
+
*/
|
|
1103
|
+
return `F${operation.value}`;
|
|
622
1104
|
},
|
|
623
1105
|
{ async: true },
|
|
624
1106
|
);
|
|
@@ -633,23 +1115,71 @@ export default class VMRunner {
|
|
|
633
1115
|
delete globalThis.__oneuptimeHostAxiosStartCallback;
|
|
634
1116
|
delete globalThis.__oneuptimeHostAxiosPollCallback;
|
|
635
1117
|
const axiosPollWaitArray = new Int32Array(new SharedArrayBuffer(4));
|
|
1118
|
+
let serializedRequestCharacters = 0;
|
|
1119
|
+
|
|
1120
|
+
function assertSerializedRequestLength(method, url, arg1, arg2) {
|
|
1121
|
+
const urlCharacters = typeof url === 'string' ? url.length : 0;
|
|
1122
|
+
const arg1Characters = typeof arg1 === 'string' ? arg1.length : 0;
|
|
1123
|
+
const arg2Characters = typeof arg2 === 'string' ? arg2.length : 0;
|
|
1124
|
+
const hasBody = ['post', 'put', 'patch'].includes(method);
|
|
1125
|
+
|
|
1126
|
+
if (urlCharacters > ${MAX_HTTP_URL_BYTES}) {
|
|
1127
|
+
throw new Error('HTTP request URL exceeded the allowed size.');
|
|
1128
|
+
}
|
|
1129
|
+
if (hasBody && arg1Characters > ${MAX_HTTP_REQUEST_BYTES}) {
|
|
1130
|
+
throw new Error('HTTP request body exceeded the allowed size.');
|
|
1131
|
+
}
|
|
1132
|
+
if (hasBody && arg2Characters > ${MAX_HTTP_CONFIG_BYTES}) {
|
|
1133
|
+
throw new Error('HTTP request config exceeded the allowed size.');
|
|
1134
|
+
}
|
|
1135
|
+
if (
|
|
1136
|
+
method === 'request' &&
|
|
1137
|
+
arg1Characters > ${MAX_HTTP_REQUEST_BYTES + MAX_HTTP_CONFIG_BYTES}
|
|
1138
|
+
) {
|
|
1139
|
+
throw new Error('HTTP request data exceeded the allowed size.');
|
|
1140
|
+
}
|
|
1141
|
+
if (
|
|
1142
|
+
!hasBody &&
|
|
1143
|
+
method !== 'request' &&
|
|
1144
|
+
arg1Characters > ${MAX_HTTP_CONFIG_BYTES}
|
|
1145
|
+
) {
|
|
1146
|
+
throw new Error('HTTP request config exceeded the allowed size.');
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
const operationCharacters =
|
|
1150
|
+
urlCharacters + arg1Characters + arg2Characters;
|
|
1151
|
+
if (
|
|
1152
|
+
serializedRequestCharacters + operationCharacters >
|
|
1153
|
+
${MAX_HTTP_REQUEST_BYTES}
|
|
1154
|
+
) {
|
|
1155
|
+
throw new Error(
|
|
1156
|
+
'Sandbox HTTP requests exceeded the allowed cumulative request size.'
|
|
1157
|
+
);
|
|
1158
|
+
}
|
|
1159
|
+
serializedRequestCharacters += operationCharacters;
|
|
1160
|
+
}
|
|
636
1161
|
|
|
637
1162
|
async function hostAxios(method, url, arg1, arg2) {
|
|
1163
|
+
assertSerializedRequestLength(method, url, arg1, arg2);
|
|
638
1164
|
const operationId = await hostAxiosStart(method, url, arg1, arg2);
|
|
639
1165
|
|
|
640
1166
|
while (true) {
|
|
641
|
-
const operation =
|
|
1167
|
+
const operation = await hostAxiosPoll(operationId);
|
|
642
1168
|
|
|
643
|
-
if (operation
|
|
1169
|
+
if (operation === 'P') {
|
|
644
1170
|
Atomics.wait(axiosPollWaitArray, 0, 0, 1);
|
|
645
1171
|
continue;
|
|
646
1172
|
}
|
|
647
1173
|
|
|
648
|
-
if (operation
|
|
649
|
-
throw new Error(operation.
|
|
1174
|
+
if (operation[0] === 'E') {
|
|
1175
|
+
throw new Error(JSON.parse(operation.slice(1)));
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
if (operation[0] !== 'F') {
|
|
1179
|
+
throw new Error('HTTP request result is invalid');
|
|
650
1180
|
}
|
|
651
1181
|
|
|
652
|
-
return operation.
|
|
1182
|
+
return operation.slice(1);
|
|
653
1183
|
}
|
|
654
1184
|
}
|
|
655
1185
|
|
|
@@ -684,20 +1214,330 @@ export default class VMRunner {
|
|
|
684
1214
|
}
|
|
685
1215
|
}
|
|
686
1216
|
|
|
1217
|
+
const base64Alphabet =
|
|
1218
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
1219
|
+
const base64Lookup = new Int16Array(128);
|
|
1220
|
+
base64Lookup.fill(-1);
|
|
1221
|
+
for (let index = 0; index < base64Alphabet.length; index += 1) {
|
|
1222
|
+
base64Lookup[base64Alphabet.charCodeAt(index)] = index;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
function decodeBase64(encoded) {
|
|
1226
|
+
const padding = encoded.endsWith('==')
|
|
1227
|
+
? 2
|
|
1228
|
+
: encoded.endsWith('=')
|
|
1229
|
+
? 1
|
|
1230
|
+
: 0;
|
|
1231
|
+
const decoded = new Uint8Array((encoded.length / 4) * 3 - padding);
|
|
1232
|
+
let outputIndex = 0;
|
|
1233
|
+
|
|
1234
|
+
for (let index = 0; index < encoded.length; index += 4) {
|
|
1235
|
+
const first = base64Lookup[encoded.charCodeAt(index)];
|
|
1236
|
+
const second = base64Lookup[encoded.charCodeAt(index + 1)];
|
|
1237
|
+
const third = encoded[index + 2] === '='
|
|
1238
|
+
? 0
|
|
1239
|
+
: base64Lookup[encoded.charCodeAt(index + 2)];
|
|
1240
|
+
const fourth = encoded[index + 3] === '='
|
|
1241
|
+
? 0
|
|
1242
|
+
: base64Lookup[encoded.charCodeAt(index + 3)];
|
|
1243
|
+
const combined =
|
|
1244
|
+
(first << 18) | (second << 12) | (third << 6) | fourth;
|
|
1245
|
+
|
|
1246
|
+
if (outputIndex < decoded.length) {
|
|
1247
|
+
decoded[outputIndex++] = (combined >> 16) & 0xff;
|
|
1248
|
+
}
|
|
1249
|
+
if (outputIndex < decoded.length) {
|
|
1250
|
+
decoded[outputIndex++] = (combined >> 8) & 0xff;
|
|
1251
|
+
}
|
|
1252
|
+
if (outputIndex < decoded.length) {
|
|
1253
|
+
decoded[outputIndex++] = combined & 0xff;
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
return decoded;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
function decodeUtf8(bytes) {
|
|
1261
|
+
const chunks = [];
|
|
1262
|
+
const codeUnits = new Uint16Array(8192);
|
|
1263
|
+
let codeUnitCount = 0;
|
|
1264
|
+
|
|
1265
|
+
function flushCodeUnits() {
|
|
1266
|
+
if (codeUnitCount === 0) return;
|
|
1267
|
+
chunks.push(
|
|
1268
|
+
String.fromCharCode.apply(
|
|
1269
|
+
null,
|
|
1270
|
+
codeUnits.subarray(0, codeUnitCount)
|
|
1271
|
+
)
|
|
1272
|
+
);
|
|
1273
|
+
codeUnitCount = 0;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
function appendCodePoint(codePoint) {
|
|
1277
|
+
if (codeUnitCount >= codeUnits.length - 1) {
|
|
1278
|
+
flushCodeUnits();
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
if (codePoint <= 0xffff) {
|
|
1282
|
+
codeUnits[codeUnitCount++] = codePoint;
|
|
1283
|
+
} else {
|
|
1284
|
+
const adjusted = codePoint - 0x10000;
|
|
1285
|
+
codeUnits[codeUnitCount++] = 0xd800 + (adjusted >> 10);
|
|
1286
|
+
codeUnits[codeUnitCount++] = 0xdc00 + (adjusted & 0x3ff);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
for (let index = 0; index < bytes.length;) {
|
|
1291
|
+
const first = bytes[index];
|
|
1292
|
+
let codePoint = 0xfffd;
|
|
1293
|
+
let width = 1;
|
|
1294
|
+
|
|
1295
|
+
if (first <= 0x7f) {
|
|
1296
|
+
codePoint = first;
|
|
1297
|
+
} else if (
|
|
1298
|
+
first >= 0xc2 &&
|
|
1299
|
+
first <= 0xdf &&
|
|
1300
|
+
index + 1 < bytes.length &&
|
|
1301
|
+
(bytes[index + 1] & 0xc0) === 0x80
|
|
1302
|
+
) {
|
|
1303
|
+
codePoint = ((first & 0x1f) << 6) | (bytes[index + 1] & 0x3f);
|
|
1304
|
+
width = 2;
|
|
1305
|
+
} else if (
|
|
1306
|
+
first >= 0xe0 &&
|
|
1307
|
+
first <= 0xef &&
|
|
1308
|
+
index + 2 < bytes.length &&
|
|
1309
|
+
(bytes[index + 1] & 0xc0) === 0x80 &&
|
|
1310
|
+
(bytes[index + 2] & 0xc0) === 0x80 &&
|
|
1311
|
+
!(first === 0xe0 && bytes[index + 1] < 0xa0) &&
|
|
1312
|
+
!(first === 0xed && bytes[index + 1] >= 0xa0)
|
|
1313
|
+
) {
|
|
1314
|
+
codePoint =
|
|
1315
|
+
((first & 0x0f) << 12) |
|
|
1316
|
+
((bytes[index + 1] & 0x3f) << 6) |
|
|
1317
|
+
(bytes[index + 2] & 0x3f);
|
|
1318
|
+
width = 3;
|
|
1319
|
+
} else if (
|
|
1320
|
+
first >= 0xf0 &&
|
|
1321
|
+
first <= 0xf4 &&
|
|
1322
|
+
index + 3 < bytes.length &&
|
|
1323
|
+
(bytes[index + 1] & 0xc0) === 0x80 &&
|
|
1324
|
+
(bytes[index + 2] & 0xc0) === 0x80 &&
|
|
1325
|
+
(bytes[index + 3] & 0xc0) === 0x80 &&
|
|
1326
|
+
!(first === 0xf0 && bytes[index + 1] < 0x90) &&
|
|
1327
|
+
!(first === 0xf4 && bytes[index + 1] >= 0x90)
|
|
1328
|
+
) {
|
|
1329
|
+
codePoint =
|
|
1330
|
+
((first & 0x07) << 18) |
|
|
1331
|
+
((bytes[index + 1] & 0x3f) << 12) |
|
|
1332
|
+
((bytes[index + 2] & 0x3f) << 6) |
|
|
1333
|
+
(bytes[index + 3] & 0x3f);
|
|
1334
|
+
width = 4;
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
appendCodePoint(codePoint);
|
|
1338
|
+
index += width;
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
flushCodeUnits();
|
|
1342
|
+
return chunks.join('');
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
function decodeSingleByte(bytes, asciiOnly) {
|
|
1346
|
+
const chunks = [];
|
|
1347
|
+
const codeUnits = new Uint16Array(8192);
|
|
1348
|
+
|
|
1349
|
+
for (let offset = 0; offset < bytes.length; offset += 8192) {
|
|
1350
|
+
const chunkLength = Math.min(8192, bytes.length - offset);
|
|
1351
|
+
for (let index = 0; index < chunkLength; index += 1) {
|
|
1352
|
+
codeUnits[index] = asciiOnly
|
|
1353
|
+
? bytes[offset + index] & 0x7f
|
|
1354
|
+
: bytes[offset + index];
|
|
1355
|
+
}
|
|
1356
|
+
chunks.push(
|
|
1357
|
+
String.fromCharCode.apply(
|
|
1358
|
+
null,
|
|
1359
|
+
codeUnits.subarray(0, chunkLength)
|
|
1360
|
+
)
|
|
1361
|
+
);
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
return chunks.join('');
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
function decodeUtf16Le(bytes) {
|
|
1368
|
+
const chunks = [];
|
|
1369
|
+
const codeUnits = new Uint16Array(8192);
|
|
1370
|
+
const codeUnitLength = Math.floor(bytes.length / 2);
|
|
1371
|
+
|
|
1372
|
+
for (let offset = 0; offset < codeUnitLength; offset += 8192) {
|
|
1373
|
+
const chunkLength = Math.min(8192, codeUnitLength - offset);
|
|
1374
|
+
for (let index = 0; index < chunkLength; index += 1) {
|
|
1375
|
+
const byteOffset = (offset + index) * 2;
|
|
1376
|
+
codeUnits[index] =
|
|
1377
|
+
bytes[byteOffset] | (bytes[byteOffset + 1] << 8);
|
|
1378
|
+
}
|
|
1379
|
+
chunks.push(
|
|
1380
|
+
String.fromCharCode.apply(
|
|
1381
|
+
null,
|
|
1382
|
+
codeUnits.subarray(0, chunkLength)
|
|
1383
|
+
)
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
return chunks.join('');
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
function encodeHex(bytes) {
|
|
1391
|
+
const alphabet = '0123456789abcdef';
|
|
1392
|
+
const chunks = [];
|
|
1393
|
+
|
|
1394
|
+
for (let offset = 0; offset < bytes.length; offset += 4096) {
|
|
1395
|
+
const end = Math.min(offset + 4096, bytes.length);
|
|
1396
|
+
let chunk = '';
|
|
1397
|
+
for (let index = offset; index < end; index += 1) {
|
|
1398
|
+
const value = bytes[index];
|
|
1399
|
+
chunk += alphabet[value >> 4] + alphabet[value & 15];
|
|
1400
|
+
}
|
|
1401
|
+
chunks.push(chunk);
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
return chunks.join('');
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
function decodeResponseText(encoded, bytes, responseEncoding) {
|
|
1408
|
+
const normalizedEncoding = responseEncoding
|
|
1409
|
+
? String(responseEncoding).toLowerCase()
|
|
1410
|
+
: 'utf8';
|
|
1411
|
+
|
|
1412
|
+
switch (normalizedEncoding) {
|
|
1413
|
+
case 'utf8':
|
|
1414
|
+
case 'utf-8':
|
|
1415
|
+
return decodeUtf8(bytes);
|
|
1416
|
+
case 'latin1':
|
|
1417
|
+
case 'binary':
|
|
1418
|
+
return decodeSingleByte(bytes, false);
|
|
1419
|
+
case 'ascii':
|
|
1420
|
+
return decodeSingleByte(bytes, true);
|
|
1421
|
+
case 'utf16le':
|
|
1422
|
+
case 'utf-16le':
|
|
1423
|
+
case 'ucs2':
|
|
1424
|
+
case 'ucs-2':
|
|
1425
|
+
return decodeUtf16Le(bytes);
|
|
1426
|
+
case 'base64':
|
|
1427
|
+
return encoded;
|
|
1428
|
+
case 'base64url':
|
|
1429
|
+
return encoded
|
|
1430
|
+
.split('+').join('-')
|
|
1431
|
+
.split('/').join('_')
|
|
1432
|
+
.replace(/=+$/, '');
|
|
1433
|
+
case 'hex':
|
|
1434
|
+
return encodeHex(bytes);
|
|
1435
|
+
default:
|
|
1436
|
+
throw new TypeError(
|
|
1437
|
+
'Unknown encoding: ' + responseEncoding
|
|
1438
|
+
);
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
|
|
687
1442
|
function parseAxiosResult(r) {
|
|
688
|
-
const
|
|
689
|
-
if (
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
1443
|
+
const metadataEnd = r.indexOf('\\n');
|
|
1444
|
+
if (metadataEnd < 0) {
|
|
1445
|
+
throw new Error('HTTP response envelope is invalid');
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
const parsed = JSON.parse(r.slice(0, metadataEnd));
|
|
1449
|
+
const dataEncoding = parsed.__oneuptimeDataEncoding;
|
|
1450
|
+
const responseEncoding = parsed.__oneuptimeResponseEncoding;
|
|
1451
|
+
const shouldParseJson = parsed.__oneuptimeShouldParseJson === true;
|
|
1452
|
+
const strictJsonParsing =
|
|
1453
|
+
parsed.__oneuptimeStrictJsonParsing === true;
|
|
1454
|
+
const responseConfig = parsed.__oneuptimeConfig || {};
|
|
1455
|
+
const hasRequest = parsed.__oneuptimeHasRequest === true;
|
|
1456
|
+
const isAxiosError = parsed.__isAxiosError === true;
|
|
1457
|
+
const errorMessage = parsed.message || 'Request failed';
|
|
1458
|
+
const errorCode = parsed.code;
|
|
1459
|
+
const errorName = parsed.name;
|
|
1460
|
+
const opaqueRequest = hasRequest
|
|
1461
|
+
? Object.freeze({ __oneuptimeOpaqueRequest: true })
|
|
1462
|
+
: undefined;
|
|
1463
|
+
|
|
1464
|
+
delete parsed.__oneuptimeDataEncoding;
|
|
1465
|
+
delete parsed.__oneuptimeResponseEncoding;
|
|
1466
|
+
delete parsed.__oneuptimeShouldParseJson;
|
|
1467
|
+
delete parsed.__oneuptimeStrictJsonParsing;
|
|
1468
|
+
delete parsed.__oneuptimeConfig;
|
|
1469
|
+
delete parsed.__oneuptimeHasRequest;
|
|
1470
|
+
delete parsed.__isAxiosError;
|
|
1471
|
+
delete parsed.message;
|
|
1472
|
+
delete parsed.code;
|
|
1473
|
+
delete parsed.name;
|
|
1474
|
+
|
|
1475
|
+
parsed.config = responseConfig;
|
|
1476
|
+
if (opaqueRequest) parsed.request = opaqueRequest;
|
|
1477
|
+
|
|
1478
|
+
function createAxiosError(message, code, name) {
|
|
1479
|
+
const err = new Error(message);
|
|
1480
|
+
err.name = name || 'AxiosError';
|
|
1481
|
+
err.code = code;
|
|
1482
|
+
err.config = responseConfig;
|
|
1483
|
+
err.request = opaqueRequest;
|
|
1484
|
+
err.response = parsed;
|
|
697
1485
|
err.isAxiosError = true;
|
|
698
1486
|
err.status = parsed.status;
|
|
699
|
-
|
|
1487
|
+
return err;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
try {
|
|
1491
|
+
const encoded = r.slice(metadataEnd + 1);
|
|
1492
|
+
const decoded = decodeBase64(encoded);
|
|
1493
|
+
|
|
1494
|
+
if (dataEncoding === 'base64-arraybuffer') {
|
|
1495
|
+
parsed.data = decoded;
|
|
1496
|
+
} else {
|
|
1497
|
+
let text = decodeResponseText(
|
|
1498
|
+
encoded,
|
|
1499
|
+
decoded,
|
|
1500
|
+
responseEncoding
|
|
1501
|
+
);
|
|
1502
|
+
|
|
1503
|
+
if (
|
|
1504
|
+
(!responseEncoding || responseEncoding === 'utf8') &&
|
|
1505
|
+
text.charCodeAt(0) === 0xfeff
|
|
1506
|
+
) {
|
|
1507
|
+
text = text.slice(1);
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
parsed.data = text;
|
|
1511
|
+
|
|
1512
|
+
if (shouldParseJson && text) {
|
|
1513
|
+
try {
|
|
1514
|
+
parsed.data = JSON.parse(text);
|
|
1515
|
+
} catch (error) {
|
|
1516
|
+
if (strictJsonParsing) {
|
|
1517
|
+
throw createAxiosError(
|
|
1518
|
+
error.message,
|
|
1519
|
+
'ERR_BAD_RESPONSE',
|
|
1520
|
+
error.name
|
|
1521
|
+
);
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
} catch (error) {
|
|
1527
|
+
if (error && error.isAxiosError) throw error;
|
|
1528
|
+
throw createAxiosError(
|
|
1529
|
+
error && error.message
|
|
1530
|
+
? error.message
|
|
1531
|
+
: 'Response could not be decoded',
|
|
1532
|
+
error && error.code,
|
|
1533
|
+
error && error.name
|
|
1534
|
+
);
|
|
700
1535
|
}
|
|
1536
|
+
|
|
1537
|
+
if (isAxiosError) {
|
|
1538
|
+
throw createAxiosError(errorMessage, errorCode, errorName);
|
|
1539
|
+
}
|
|
1540
|
+
|
|
701
1541
|
return parsed;
|
|
702
1542
|
}
|
|
703
1543
|
|
|
@@ -710,6 +1550,13 @@ export default class VMRunner {
|
|
|
710
1550
|
if (defaults.headers && overrides.headers) {
|
|
711
1551
|
merged.headers = Object.assign({}, defaults.headers, overrides.headers);
|
|
712
1552
|
}
|
|
1553
|
+
if (defaults.transitional && overrides.transitional) {
|
|
1554
|
+
merged.transitional = Object.assign(
|
|
1555
|
+
{},
|
|
1556
|
+
defaults.transitional,
|
|
1557
|
+
overrides.transitional
|
|
1558
|
+
);
|
|
1559
|
+
}
|
|
713
1560
|
return merged;
|
|
714
1561
|
}
|
|
715
1562
|
|
|
@@ -774,6 +1621,9 @@ export default class VMRunner {
|
|
|
774
1621
|
const r = await hostAxios('delete', url, merged ? JSON.stringify(merged) : undefined);
|
|
775
1622
|
return parseAxiosResult(r);
|
|
776
1623
|
};
|
|
1624
|
+
instance.isAxiosError = (payload) => {
|
|
1625
|
+
return Boolean(payload && payload.isAxiosError === true);
|
|
1626
|
+
};
|
|
777
1627
|
instance.create = (instanceDefaults) => {
|
|
778
1628
|
if (instanceDefaults) assertNoFunctions(instanceDefaults, 'defaults');
|
|
779
1629
|
const combinedDefaults = mergeConfig(instanceDefaults);
|
|
@@ -1002,6 +1852,34 @@ export default class VMRunner {
|
|
|
1002
1852
|
let result: unknown;
|
|
1003
1853
|
let scriptError: Error | undefined;
|
|
1004
1854
|
|
|
1855
|
+
/*
|
|
1856
|
+
* Keep Node's event loop turning for as long as sandboxed code is
|
|
1857
|
+
* running.
|
|
1858
|
+
*
|
|
1859
|
+
* Every host bridge the sandbox has - axios, sleep, the log sink - is an
|
|
1860
|
+
* isolated-vm async callback: the isolate posts a call onto THIS thread,
|
|
1861
|
+
* this thread answers it, and the isolate resumes. Each of those hops
|
|
1862
|
+
* only makes progress when the event loop takes a turn, and a loop with
|
|
1863
|
+
* nothing else to do parks until its next TIMER rather than spinning. On
|
|
1864
|
+
* an otherwise idle process the nearest timer is usually the overall
|
|
1865
|
+
* timeout armed just below, so a single `await sleep(0)` - or a request
|
|
1866
|
+
* the SSRF guard refuses synchronously, in microseconds - came back
|
|
1867
|
+
* 20 seconds later as "Script execution timed out". Under Jest the
|
|
1868
|
+
* nearest timer was whatever the runner happened to have queued, which
|
|
1869
|
+
* is why the same test took 100ms on one run and 900ms on the next, and
|
|
1870
|
+
* why the VMRunner suites failed on CI while passing locally.
|
|
1871
|
+
*
|
|
1872
|
+
* A no-op ticker gives the loop a reason to wake. It runs only while a
|
|
1873
|
+
* script is in flight and is cleared before this method returns.
|
|
1874
|
+
*/
|
|
1875
|
+
const hostBridgeTicker: ReturnType<typeof global.setInterval> =
|
|
1876
|
+
global.setInterval((): void => {
|
|
1877
|
+
/*
|
|
1878
|
+
* Intentionally empty: existing only so libuv wakes on a known
|
|
1879
|
+
* cadence instead of sleeping until some unrelated timer.
|
|
1880
|
+
*/
|
|
1881
|
+
}, HOST_BRIDGE_TICK_MS);
|
|
1882
|
+
|
|
1005
1883
|
try {
|
|
1006
1884
|
// Run with overall timeout covering both CPU and I/O wait.
|
|
1007
1885
|
const resultPromise: Promise<unknown> = context.eval(wrappedCode, {
|
|
@@ -1027,6 +1905,8 @@ export default class VMRunner {
|
|
|
1027
1905
|
result = await Promise.race([resultPromise, overallTimeout]);
|
|
1028
1906
|
} catch (error: unknown) {
|
|
1029
1907
|
scriptError = sanitizeScriptError(error);
|
|
1908
|
+
} finally {
|
|
1909
|
+
global.clearInterval(hostBridgeTicker);
|
|
1030
1910
|
}
|
|
1031
1911
|
|
|
1032
1912
|
// Parse the JSON string returned from inside the isolate
|