@oneuptime/common 12.0.34 → 13.0.1
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/DatabaseModels/Alert.ts +55 -0
- package/Models/DatabaseModels/CloudResource.ts +45 -7
- package/Models/DatabaseModels/CodeRepository.ts +85 -0
- package/Models/DatabaseModels/GlobalConfig.ts +12 -12
- package/Models/DatabaseModels/GoogleSecOpsConnection.ts +57 -7
- package/Models/DatabaseModels/GoogleSecOpsConnectionRun.ts +263 -0
- package/Models/DatabaseModels/Incident.ts +55 -0
- package/Models/DatabaseModels/Index.ts +16 -0
- package/Models/DatabaseModels/InventoryItem.ts +44 -1
- package/Models/DatabaseModels/NetworkDevice.ts +126 -0
- package/Models/DatabaseModels/ScheduledMaintenance.ts +55 -0
- package/Models/DatabaseModels/User.ts +51 -2
- package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +43 -2
- package/Models/DatabaseModels/UserWebAuthn.ts +17 -0
- package/Models/DatabaseModels/VMwareResource.ts +1149 -0
- package/Models/DatabaseModels/VMwareVCenter.ts +1122 -0
- package/Models/DatabaseModels/VMwareVCenterFeed.ts +625 -0
- package/Models/DatabaseModels/VMwareVCenterLabelRule.ts +514 -0
- package/Models/DatabaseModels/VMwareVCenterOwnerRule.ts +596 -0
- package/Models/DatabaseModels/VMwareVCenterOwnerTeam.ts +485 -0
- package/Models/DatabaseModels/VMwareVCenterOwnerUser.ts +484 -0
- package/Models/DatabaseModels/WorkflowVariable.ts +22 -1
- package/Server/API/AIAgentDataAPI.ts +79 -4
- package/Server/API/AIAgentGitHubAPI.ts +523 -0
- package/Server/API/AIChatAPI.ts +20 -1
- package/Server/API/BillingAPI.ts +33 -0
- package/Server/API/DashboardAPI.ts +10 -0
- package/Server/API/GitHubAPI.ts +47 -5
- package/Server/API/GoogleSecOpsConnectionAPI.ts +79 -0
- package/Server/API/UserWebAuthnAPI.ts +21 -1
- package/Server/API/VMwareResourceAPI.ts +143 -0
- package/Server/EnvironmentConfig.ts +47 -16
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791800000000-SplitWebAuthnChallengeByPurpose.ts +68 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791900000000-AddSeverityAndStateToNotificationEmailRollup.ts +26 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792000000000-AddVMwareTables.ts +636 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792100000000-AddGitHubCommandSettingsToCodeRepository.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792200000000-AddUserWebAuthnPurpose.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792300000000-AddGoogleSecOpsDiagnostics.ts +83 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
- package/Server/Infrastructure/Redis.ts +8 -8
- package/Server/Infrastructure/Status.ts +10 -4
- package/Server/Middleware/IdentityRateLimit.ts +101 -0
- package/Server/Services/AIRunService.ts +13 -0
- package/Server/Services/BillingPaymentMethodService.ts +99 -28
- package/Server/Services/BillingService.ts +287 -20
- package/Server/Services/CloudResourceInstanceService.ts +70 -0
- package/Server/Services/DatabaseService.ts +65 -13
- package/Server/Services/ExceptionAggregationService.ts +1 -0
- package/Server/Services/GoogleSecOpsConnectionRunService.ts +10 -0
- package/Server/Services/GoogleSecOpsConnectionService.ts +12 -0
- package/Server/Services/Index.ts +16 -0
- package/Server/Services/InventoryItemService.ts +31 -1
- package/Server/Services/LogAggregationService.ts +1 -0
- package/Server/Services/MetricAggregationService.ts +1 -0
- package/Server/Services/MobilePasskeyLoginService.ts +216 -0
- package/Server/Services/MonitorService.ts +51 -1
- package/Server/Services/MonitorTemplateService.ts +218 -35
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +481 -42
- package/Server/Services/NetworkDeviceAutoImportRuleService.ts +176 -2
- package/Server/Services/NetworkDeviceDiscoveryScanService.ts +87 -2
- package/Server/Services/NetworkDeviceService.ts +69 -0
- package/Server/Services/OpenTelemetryIngestService.ts +17 -0
- package/Server/Services/PayAsYouGoBillingService.ts +446 -0
- package/Server/Services/ProjectService.ts +46 -2
- package/Server/Services/ServerlessFunctionInstanceService.ts +71 -0
- package/Server/Services/TeamMemberService.ts +96 -36
- package/Server/Services/TelemetryIngestionKeyService.ts +80 -10
- package/Server/Services/TelemetryUsageBillingService.ts +95 -5
- package/Server/Services/TraceAggregationService.ts +5 -4
- package/Server/Services/UserNotificationRuleService.ts +76 -25
- package/Server/Services/UserWebAuthnService.ts +592 -133
- package/Server/Services/VMwareResourceService.ts +648 -0
- package/Server/Services/VMwareVCenterFeedService.ts +99 -0
- package/Server/Services/VMwareVCenterLabelRuleEngineService.ts +240 -0
- package/Server/Services/VMwareVCenterLabelRuleService.ts +14 -0
- package/Server/Services/VMwareVCenterOwnerRuleEngineService.ts +252 -0
- package/Server/Services/VMwareVCenterOwnerRuleService.ts +14 -0
- package/Server/Services/VMwareVCenterOwnerTeamService.ts +139 -0
- package/Server/Services/VMwareVCenterOwnerUserService.ts +133 -0
- package/Server/Services/VMwareVCenterService.ts +629 -0
- package/Server/Services/WorkflowVariableService.ts +203 -0
- package/Server/Types/Billing/MeteredPlan/ActiveMonitoringMeteredPlan.ts +17 -0
- package/Server/Types/Billing/MeteredPlan/TelemetryMeteredPlan.ts +31 -1
- package/Server/Types/Database/Permissions/ReadPermission.ts +45 -5
- package/Server/Types/Database/QueryUtil.ts +56 -0
- package/Server/Types/Markdown.ts +93 -1
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +7 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubAgentTaskTrigger.ts +341 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubCommandAuthorizer.ts +274 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubCommandParser.ts +375 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubConversation.ts +846 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubReplyComposer.ts +360 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubRunReply.ts +421 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubWebhookEvents.ts +140 -0
- package/Server/Utils/CodeRepository/GitHub/GitHubWebhookHandler.ts +906 -0
- package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +225 -17
- package/Server/Utils/DataSource/EgressGuard.ts +160 -15
- package/Server/Utils/Database/TruncateColumnValue.ts +1 -1
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +12 -1
- package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +35 -2
- package/Server/Utils/EmailRollup/EmailRollupWriter.ts +44 -0
- package/Server/Utils/LogRedaction.ts +2 -1
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +82 -35
- package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +31 -5
- package/Server/Utils/Monitor/MonitorAlert.ts +1 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +502 -38
- 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/MonitorMaintenanceSuppression.ts +26 -4
- package/Server/Utils/Monitor/MonitorResourceContext.ts +5 -3
- package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +14 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -0
- package/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.ts +158 -0
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +27 -0
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +26 -0
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +28 -5
- package/Server/Utils/ResourceFeed/ResourceFeedUtil.ts +3 -3
- package/Server/Utils/SecurityEvent/ConnectorErrorMessage.ts +14 -9
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.ts +116 -84
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +594 -195
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.ts +466 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +16 -1
- package/Server/Utils/Telemetry/ResourceHeartbeat.ts +2 -1
- package/Server/Utils/Telemetry/TelemetryEntity.ts +264 -10
- package/Server/Utils/Telemetry/VMwareSnapshotScan.ts +1352 -0
- package/Tests/App/Accounts/LoginPasskey.test.tsx +529 -0
- package/Tests/App/Accounts/MobilePasskey.test.tsx +620 -0
- package/Tests/App/Accounts/PasswordRequirements.test.tsx +254 -0
- package/Tests/App/Accounts/RegisterPassword.test.tsx +553 -0
- package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +32 -0
- package/Tests/App/Dashboard/AdoptedDeviceDrawer.test.tsx +374 -0
- package/Tests/App/Dashboard/AskAiAvailability.test.ts +224 -0
- package/Tests/App/Dashboard/AskAiDisabled.test.tsx +432 -0
- package/Tests/App/Dashboard/BackupCodes.test.tsx +414 -0
- package/Tests/App/Dashboard/BillingPaidUsageFlow.test.tsx +530 -0
- package/Tests/App/Dashboard/BillingPaymentMethodForm.test.tsx +195 -0
- package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +199 -0
- package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +198 -0
- package/Tests/App/Dashboard/CloudDocumentationMarkdown.test.ts +215 -0
- package/Tests/App/Dashboard/CloudFleetSummary.test.ts +183 -0
- package/Tests/App/Dashboard/CloudFleetSummaryComponent.test.tsx +248 -0
- package/Tests/App/Dashboard/CloudResourceTelemetryScope.test.ts +215 -0
- package/Tests/App/Dashboard/CriteriaFilterDefaults.test.ts +3 -0
- package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +441 -0
- package/Tests/App/Dashboard/DashboardLabelVariables.test.tsx +580 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +458 -0
- package/Tests/App/Dashboard/DashboardMonitorLabelVariable.test.tsx +438 -0
- package/Tests/App/Dashboard/DashboardToolbarPopupLayering.test.tsx +566 -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/DiscoveryScanLivePage.test.tsx +376 -0
- package/Tests/App/Dashboard/DiscoveryScanLiveUpdates.test.tsx +642 -0
- package/Tests/App/Dashboard/DiscoveryScanProgress.test.tsx +267 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +69 -231
- package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +163 -0
- package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +244 -0
- package/Tests/App/Dashboard/GoogleSecOpsDiagnostics.test.tsx +724 -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/MonitorTemplateSyncFields.test.tsx +539 -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/OnCallLayerCardOverrides.test.tsx +24 -7
- package/Tests/App/Dashboard/OnCallOverridePresentation.test.ts +496 -0
- package/Tests/App/Dashboard/OnCallScheduleOverrideClarity.test.tsx +677 -0
- package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +31 -3
- package/Tests/App/Dashboard/PaidUsageConsent.test.tsx +180 -0
- package/Tests/App/Dashboard/PasskeySettings.test.tsx +1220 -0
- package/Tests/App/Dashboard/PayAsYouGoConsentGate.test.tsx +176 -275
- package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +380 -233
- package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +3 -23
- package/Tests/App/Dashboard/ResourceFeed.test.tsx +1 -0
- package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
- 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/TwoFactorStatus.test.tsx +260 -0
- package/Tests/App/Dashboard/UserSettingsEmailPreferences.test.tsx +603 -0
- package/Tests/App/Dashboard/UserSettingsNotificationSettings.test.tsx +324 -0
- package/Tests/App/Dashboard/VMwareDashboardWidgets.test.ts +573 -0
- package/Tests/App/Dashboard/WidgetCatalog.test.ts +2 -0
- package/Tests/App/Dashboard/WorkflowVariablesTable.test.tsx +768 -0
- package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +13 -4
- package/Tests/App/StatusPage/StatusPageOidcOrigin.test.tsx +223 -0
- package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +532 -40
- package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +19 -2
- package/Tests/Fixtures/MobilePasskeyUser.json +8 -0
- package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +25 -6
- package/Tests/Models/DatabaseModels/VMwareModels.test.ts +1134 -0
- package/Tests/Models/InventoryItemStatus.test.ts +147 -0
- package/Tests/Models/NetworkDeviceMacAddressColumn.test.ts +294 -0
- package/Tests/Models/RunnerVersionLabel.test.ts +4 -2
- package/Tests/Server/API/AIChatProvidersAIEnabled.test.ts +259 -0
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +31 -2
- package/Tests/Server/API/BillingPayAsYouGoStatus.test.ts +116 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +158 -1
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +13 -2
- package/Tests/Server/API/GitHubWebhookSignature.test.ts +368 -0
- package/Tests/Server/API/GoogleSecOpsConnectionAPI.test.ts +248 -0
- package/Tests/Server/API/UserWebAuthnAuthenticationOptionsRoute.test.ts +330 -0
- package/Tests/Server/API/UserWebAuthnPasskeyAPI.test.ts +172 -0
- package/Tests/Server/API/VMwareResourceAPI.test.ts +546 -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 +62 -23
- package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupMetadataMigration.test.ts +85 -0
- package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +34 -3
- package/Tests/Server/Infrastructure/ValkeyDeploymentConfig.test.ts +265 -0
- package/Tests/Server/Middleware/HttpMetricsMiddleware.test.ts +382 -0
- package/Tests/Server/Middleware/PasskeyRateLimit.test.ts +141 -0
- package/Tests/Server/Middleware/SCIMAuthorization.test.ts +525 -0
- package/Tests/Server/Services/AutoImportRuleRearmRecentScans.test.ts +343 -0
- package/Tests/Server/Services/AutoImportRuleWriteRearmsScans.test.ts +381 -0
- package/Tests/Server/Services/BillingPaymentMethodServiceSync.test.ts +175 -0
- package/Tests/Server/Services/BillingService.test.ts +26 -11
- package/Tests/Server/Services/BillingServiceMeteredPaymentAuthorization.test.ts +245 -0
- package/Tests/Server/Services/BillingServicePaymentMethodReads.test.ts +362 -0
- package/Tests/Server/Services/CloudResourceInstanceStalePrune.test.ts +188 -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 +16 -2
- package/Tests/Server/Services/GoogleSecOpsDiagnosticsModel.test.ts +153 -0
- package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +13 -0
- package/Tests/Server/Services/InventoryItemManualCreate.test.ts +105 -0
- package/Tests/Server/Services/InventoryItemPromotionGate.test.ts +183 -0
- package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +36 -0
- package/Tests/Server/Services/InventoryUpsertTruncationGuard.test.ts +151 -0
- package/Tests/Server/Services/MobilePasskeyLoginIntegration.test.ts +231 -0
- package/Tests/Server/Services/MobilePasskeyLoginService.test.ts +315 -0
- package/Tests/Server/Services/MonitorPayAsYouGoBilling.test.ts +302 -0
- package/Tests/Server/Services/MonitorTemplateServiceCustomFieldSync.test.ts +502 -0
- package/Tests/Server/Services/MonitorTemplateServiceFieldSync.test.ts +994 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +1133 -81
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +22 -0
- package/Tests/Server/Services/NetworkDeviceDiscoveryScanRegistration.test.ts +520 -0
- package/Tests/Server/Services/NetworkDeviceMacAddressNormalization.test.ts +572 -0
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +7 -1
- package/Tests/Server/Services/PayAsYouGoBillingService.test.ts +857 -0
- package/Tests/Server/Services/PayAsYouGoStripeRateLimitBudget.test.ts +379 -0
- package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +99 -1
- package/Tests/Server/Services/ProjectServiceSubscriptionSeats.test.ts +134 -0
- package/Tests/Server/Services/ResourceFeedServices.test.ts +3 -2
- package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +32 -6
- package/Tests/Server/Services/SecurityEventLastErrorColumnWidth.test.ts +363 -175
- package/Tests/Server/Services/ServerlessFunctionInstanceStalePrune.test.ts +200 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +3 -0
- package/Tests/Server/Services/TeamMemberBillingSeatSync.test.ts +762 -0
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +3 -0
- package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +72 -0
- package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +17 -4
- package/Tests/Server/Services/TelemetryPayAsYouGoBilling.test.ts +355 -0
- package/Tests/Server/Services/TraceAnalyticsResourceDisplayNames.test.ts +41 -4
- package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +37 -0
- package/Tests/Server/Services/UserWebAuthnPasskeyIntegration.test.ts +401 -0
- package/Tests/Server/Services/UserWebAuthnPasskeyService.test.ts +769 -0
- package/Tests/Server/Services/UserWebAuthnUserVerification.test.ts +649 -0
- package/Tests/Server/Services/VMwareResourceService.test.ts +945 -0
- package/Tests/Server/Services/VMwareVCenterService.test.ts +722 -0
- package/Tests/Server/Services/WorkflowVariableRenameUniqueness.test.ts +842 -0
- package/Tests/Server/TestingUtils/PasskeyHttpIntegration.ts +102 -0
- package/Tests/Server/TestingUtils/SecurityKey.ts +464 -0
- package/Tests/Server/TestingUtils/WebAuthnServiceMocks.ts +60 -0
- package/Tests/Server/Types/Billing/PayAsYouGoMeteredAuthorization.test.ts +573 -0
- package/Tests/Server/Types/Database/InventoryStatusPostgres.test.ts +368 -0
- package/Tests/Server/Types/Database/Permissions/ProjectCustomerSupportAccessColumn.test.ts +261 -0
- package/Tests/Server/Types/Database/Permissions/ReadBlockPermission.test.ts +261 -14
- package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +95 -0
- 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/CodeRepository/GitHubAgentTaskTrigger.test.ts +2101 -0
- package/Tests/Server/Utils/CodeRepository/GitHubCommandAuthorizer.test.ts +883 -0
- package/Tests/Server/Utils/CodeRepository/GitHubCommandParser.test.ts +1474 -0
- package/Tests/Server/Utils/CodeRepository/GitHubConversation.test.ts +1526 -0
- package/Tests/Server/Utils/CodeRepository/GitHubReplyComposer.test.ts +1389 -0
- package/Tests/Server/Utils/CodeRepository/GitHubRunReply.test.ts +1707 -0
- package/Tests/Server/Utils/CodeRepository/GitHubWebhookHandler.test.ts +2202 -0
- package/Tests/Server/Utils/CustomField/CustomFieldMappingRegistry.test.ts +436 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +559 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +896 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1 -1
- package/Tests/Server/Utils/EmailRollup/EmailRollupMetadataIntegration.test.ts +246 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +309 -4
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +6 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +185 -0
- package/Tests/Server/Utils/EventLoop.test.ts +359 -0
- package/Tests/Server/Utils/JsonWebToken.test.ts +30 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +33 -0
- package/Tests/Server/Utils/Monitor/CapturedMetricAttributeUtil.test.ts +2 -1
- package/Tests/Server/Utils/Monitor/Criteria/CompareCriteria.test.ts +242 -0
- package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +13 -7
- package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +29 -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/Criteria/TelemetryStepMetricAlias.test.ts +10 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +66 -1
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEmailEvalLogAgreement.test.ts +280 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +586 -10
- 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/MonitorDependencySuppressionCreatorSkip.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +60 -1
- package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +60 -0
- package/Tests/Server/Utils/Monitor/MonitorRootCauseTargetResolution.test.ts +423 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +6 -0
- package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +1 -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/PerSeriesSecondEntityAlerting.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +46 -2
- package/Tests/Server/Utils/SecurityEvent/ConnectorErrorMessage.test.ts +81 -45
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.test.ts +711 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClickhouseIntegration.test.ts +223 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClient.test.ts +69 -1
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsDiagnostics.test.ts +838 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsErrorHandling.test.ts +241 -28
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsHttpIntegration.test.ts +651 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +11 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +13 -12
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +112 -127
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsRequestContract.test.ts +12 -18
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsResponseParsing.test.ts +43 -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/TelemetryEntity.test.ts +691 -8
- package/Tests/Server/Utils/Telemetry/VMwareSnapshotScan.test.ts +1748 -0
- package/Tests/Types/Cloud/CloudPlatform.test.ts +574 -0
- package/Tests/Types/Database/IncludesAnyOfGroups.test.ts +106 -0
- package/Tests/Types/JSONFunctions.test.ts +40 -0
- package/Tests/Types/Monitor/MetricAndProfileDefaultCriteria.test.ts +2 -0
- package/Tests/Types/Monitor/MonitorCriteriaMetricVariables.test.ts +9 -0
- package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorStepInfraMonitorUtils.test.ts +53 -8
- package/Tests/Types/Monitor/MonitorStepInfrastructureMonitors.test.ts +97 -0
- package/Tests/Types/Monitor/MonitorStepMetricViewConfigUtil.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorStepTemplateSyncFields.test.ts +107 -0
- package/Tests/Types/Monitor/MonitorTemplateSyncField.test.ts +172 -0
- package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +2 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +1 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +9 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
- package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +131 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +10 -0
- package/Tests/Types/Monitor/VMwareAlertTemplates.test.ts +1608 -0
- package/Tests/Types/Monitor/VMwareMetricCatalog.test.ts +488 -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/OnCallDutyPolicy/OverrideProvenance.test.ts +295 -0
- package/Tests/Types/Runner/RunnerLiveStatus.test.ts +2 -2
- package/Tests/Types/SignupPassword.test.ts +205 -0
- package/Tests/Types/StatusPage/StatusPageLanguage.test.ts +44 -0
- package/Tests/Types/SupportedLanguages.test.ts +119 -0
- package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +19 -0
- package/Tests/Types/Telemetry/InventoryLiveness.test.ts +99 -0
- package/Tests/UI/ColorPickerBuild.test.ts +86 -0
- package/Tests/UI/Components/Breadcrumbs.test.tsx +32 -0
- package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +160 -0
- package/Tests/UI/Components/Forms/ModelFormPreservesUserInput.test.tsx +937 -0
- package/Tests/UI/Components/Forms/ModelFormWriteOnlyColumnSelect.test.tsx +230 -0
- package/Tests/UI/Components/Forms/ValidationFormSteps.test.ts +3 -4
- package/Tests/UI/Components/LabelRuleImportExport.test.tsx +907 -0
- package/Tests/UI/Components/ModelTable/ModelTableCreateAfterEdit.test.tsx +514 -0
- package/Tests/UI/Components/MonitorGraphs/Uptime.test.tsx +301 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +2 -1
- package/Tests/UI/Components/TooltipLazyContent.test.tsx +373 -0
- package/Tests/UI/MicrosoftTeams/MicrosoftTeamsMessagingEndpointGuidance.test.tsx +43 -12
- package/Tests/UI/ReactDomBuild.test.ts +104 -0
- package/Tests/UI/ReactRouterSingletonBuild.test.ts +143 -0
- package/Tests/UI/Rum/ReplayHeader.test.tsx +10 -2
- package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +514 -0
- package/Tests/UI/Rum/ReplayTimeFormat.test.ts +94 -0
- package/Tests/UI/Rum/ReplayUi.test.tsx +559 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +153 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +30 -0
- package/Tests/UI/Utils/DashboardStackingLayers.test.ts +197 -0
- package/Tests/UI/Utils/LabelRuleImportExport.test.ts +546 -0
- package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +109 -2
- package/Tests/UI/Utils/UseDashboardGridDnd.test.tsx +7 -2
- package/Tests/UI/Utils/UserEmailRegistrationStatus.test.tsx +295 -0
- package/Tests/UI/Utils/WebAuthn.test.ts +265 -0
- package/Tests/Utils/Dashboard/Components/DashboardComponentDefaults.test.ts +5 -0
- package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +11 -1
- package/Tests/Utils/Dashboard/Components/DashboardVMwareListComponents.test.ts +548 -0
- package/Tests/Utils/Dashboard/DashboardResourceListSharedArgs.test.ts +17 -3
- package/Tests/Utils/Dashboard/LabelVariable.test.ts +257 -0
- package/Tests/Utils/Dashboard/VariableUrlState.test.ts +144 -14
- package/Tests/Utils/LabelRuleImportExport.test.ts +583 -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/MonitorSummarySnapshotUtil.test.ts +1 -0
- package/Tests/Utils/Monitor/MonitorTemplateCustomFieldUtil.test.ts +218 -0
- package/Tests/Utils/Monitor/MonitorTemplateSyncUtil.test.ts +590 -0
- package/Tests/Utils/Monitor/NetworkTopologyEndpointAdoption.test.ts +1755 -0
- package/Tests/Utils/NetworkAutomation/AutoImportRunChain.test.ts +320 -0
- package/Tests/Utils/RequestFailedDetails.test.ts +325 -0
- package/Tests/Utils/Telemetry/CloudInstanceIdentity.test.ts +255 -0
- package/Tests/Utils/Telemetry/EntityRelationship.test.ts +167 -0
- package/Tests/Utils/WebAuthnTestUtil.ts +79 -0
- package/Tests/__mocks__/simplewebauthn.js +33 -4
- package/Types/AI/CodeFixTaskContext.ts +122 -0
- package/Types/AI/CodeFixTaskType.ts +62 -0
- package/Types/Accounts/AccountsLanguage.ts +1 -0
- package/Types/AdminDashboard/AdminDashboardLanguage.ts +1 -0
- package/Types/BaseDatabase/IncludesAnyOfGroups.ts +77 -0
- package/Types/Calendar/CalendarEvent.ts +16 -0
- package/Types/Cloud/CloudPlatform.ts +372 -0
- package/Types/CodeRepository/GitHubCommand.ts +69 -0
- package/Types/Dashboard/DashboardComponentType.ts +2 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +2 -0
- package/Types/Dashboard/DashboardComponents/DashboardMonitorListComponent.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardVMwareHostListComponent.ts +23 -0
- package/Types/Dashboard/DashboardComponents/DashboardVMwareVirtualMachineListComponent.ts +30 -0
- package/Types/Dashboard/DashboardLanguage.ts +1 -0
- package/Types/Dashboard/DashboardTemplates.ts +314 -0
- package/Types/Dashboard/DashboardVariable.ts +8 -0
- package/Types/Docs/DocsLanguage.ts +1 -0
- package/Types/Exception/EgressGuardException.ts +65 -0
- package/Types/Icon/IconProp.ts +1 -0
- package/Types/JSON.ts +4 -0
- package/Types/JSONFunctions.ts +16 -0
- package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +36 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +1 -0
- package/Types/Monitor/MonitorStep.ts +78 -17
- package/Types/Monitor/MonitorStepMetricViewConfigUtil.ts +1 -0
- package/Types/Monitor/MonitorStepVMwareMonitor.ts +127 -0
- package/Types/Monitor/MonitorTemplateSyncField.ts +291 -0
- package/Types/Monitor/MonitorType.ts +24 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +33 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +2 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +3 -0
- package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +158 -0
- package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +61 -0
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +13 -0
- package/Types/Monitor/VMwareAlertTemplates.ts +1070 -0
- package/Types/Monitor/VMwareMetricCatalog.ts +914 -0
- package/Types/NetworkAutomation/RuleRunResult.ts +402 -13
- package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +29 -0
- package/Types/OnCallDutyPolicy/UserOverrideUtil.ts +16 -0
- package/Types/Password.ts +84 -5
- package/Types/Permission.ts +265 -0
- package/Types/Probe/RequestFailedDetails.ts +7 -0
- package/Types/Runner/RunnerLiveStatus.ts +1 -1
- package/Types/SecurityEvent/GoogleSecOpsDiagnostics.ts +56 -0
- package/Types/SerializableObjectDictionary.ts +4 -0
- package/Types/StatusPage/StatusPageLanguage.ts +1 -0
- package/Types/Telemetry/EntityType.ts +21 -0
- package/Types/Telemetry/InventoryLiveness.ts +56 -0
- package/Types/Telemetry/ServiceType.ts +1 -0
- package/Typings/Index.d.ts +63 -0
- package/UI/Components/Breadcrumbs/Breadcrumbs.tsx +2 -2
- package/UI/Components/CSVFileUpload/CSVFileUpload.tsx +9 -2
- package/UI/Components/Calendar/Calendar.css +78 -0
- package/UI/Components/Calendar/Calendar.tsx +28 -3
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +46 -21
- package/UI/Components/Dashboard/DashboardVariableControl.tsx +285 -0
- package/UI/Components/Forms/BasicForm.tsx +44 -2
- package/UI/Components/Forms/Fields/ColorPicker.tsx +2 -1
- package/UI/Components/Forms/Fields/FormField.tsx +16 -3
- package/UI/Components/Forms/ModelForm.tsx +159 -5
- package/UI/Components/Forms/Types/Field.ts +8 -1
- package/UI/Components/Graphs/DayUptimeGraph.tsx +8 -10
- package/UI/Components/Icon/Icon.tsx +16 -0
- package/UI/Components/Input/Input.tsx +42 -7
- package/UI/Components/LabelRule/ImportLabelRulesModal.tsx +441 -0
- package/UI/Components/LabelRule/LabelRuleTable.tsx +142 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +22 -5
- package/UI/Components/ModelTable/ModelTable.tsx +14 -6
- package/UI/Components/MonitorGraphs/Uptime.tsx +17 -27
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +3 -1
- package/UI/Components/Tooltip/Tooltip.tsx +52 -6
- package/UI/Utils/DashboardStackingLayers.ts +85 -0
- package/UI/Utils/LabelRuleImportExport.ts +310 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +4 -3
- package/UI/Utils/TelemetryService.ts +4 -3
- package/UI/Utils/UseDashboardGridDnd.ts +4 -1
- package/UI/Utils/UserEmailRegistrationStatus.ts +33 -5
- package/UI/Utils/WebAuthn.ts +220 -0
- package/UI/esbuild-config.js +10 -0
- package/Utils/API.ts +34 -0
- package/Utils/Dashboard/Components/DashboardMonitorListComponent.ts +12 -1
- package/Utils/Dashboard/Components/DashboardVMwareHostListComponent.ts +38 -0
- package/Utils/Dashboard/Components/DashboardVMwareResourceListShared.ts +70 -0
- package/Utils/Dashboard/Components/DashboardVMwareVirtualMachineListComponent.ts +76 -0
- package/Utils/Dashboard/Components/Index.ts +16 -0
- package/Utils/Dashboard/LabelVariable.ts +152 -0
- package/Utils/Dashboard/VariableUrlState.ts +27 -5
- package/Utils/LabelRuleImportExport.ts +496 -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/MonitorTemplateSyncUtil.ts +164 -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 +8 -0
- package/Utils/Telemetry/CloudInstanceIdentity.ts +94 -0
- package/Utils/Telemetry/EntityKey.ts +19 -0
- package/Utils/Telemetry/EntityRelationship.ts +19 -0
- package/build/dist/Models/DatabaseModels/Alert.js +54 -0
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CloudResource.js +44 -7
- package/build/dist/Models/DatabaseModels/CloudResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CodeRepository.js +87 -0
- package/build/dist/Models/DatabaseModels/CodeRepository.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/GoogleSecOpsConnection.js +60 -7
- package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js +287 -0
- package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Incident.js +54 -0
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +16 -0
- package/build/dist/Models/DatabaseModels/Index.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/NetworkDevice.js +128 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +57 -4
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +47 -2
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWebAuthn.js +18 -0
- package/build/dist/Models/DatabaseModels/UserWebAuthn.js.map +1 -1
- package/build/dist/Models/DatabaseModels/VMwareResource.js +1201 -0
- package/build/dist/Models/DatabaseModels/VMwareResource.js.map +1 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js +1149 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterFeed.js +648 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterFeed.js.map +1 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterLabelRule.js +522 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerRule.js +603 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerTeam.js +503 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerUser.js +502 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +22 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Server/API/AIAgentDataAPI.js +63 -3
- package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
- package/build/dist/Server/API/AIAgentGitHubAPI.js +363 -0
- package/build/dist/Server/API/AIAgentGitHubAPI.js.map +1 -0
- package/build/dist/Server/API/AIChatAPI.js +19 -1
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/BillingAPI.js +22 -0
- package/build/dist/Server/API/BillingAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +10 -0
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/GitHubAPI.js +33 -5
- package/build/dist/Server/API/GitHubAPI.js.map +1 -1
- package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js +56 -0
- package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js.map +1 -0
- package/build/dist/Server/API/UserWebAuthnAPI.js +17 -1
- package/build/dist/Server/API/UserWebAuthnAPI.js.map +1 -1
- package/build/dist/Server/API/VMwareResourceAPI.js +106 -0
- package/build/dist/Server/API/VMwareResourceAPI.js.map +1 -0
- package/build/dist/Server/EnvironmentConfig.js +44 -12
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- 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/1791800000000-SplitWebAuthnChallengeByPurpose.js +41 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791800000000-SplitWebAuthnChallengeByPurpose.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791900000000-AddSeverityAndStateToNotificationEmailRollup.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791900000000-AddSeverityAndStateToNotificationEmailRollup.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792000000000-AddVMwareTables.js +241 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792000000000-AddVMwareTables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792100000000-AddGitHubCommandSettingsToCodeRepository.js +36 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792100000000-AddGitHubCommandSettingsToCodeRepository.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792200000000-AddUserWebAuthnPurpose.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792200000000-AddUserWebAuthnPurpose.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792300000000-AddGoogleSecOpsDiagnostics.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792300000000-AddGoogleSecOpsDiagnostics.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.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/Status.js +10 -4
- package/build/dist/Server/Infrastructure/Status.js.map +1 -1
- package/build/dist/Server/Middleware/IdentityRateLimit.js +80 -0
- package/build/dist/Server/Middleware/IdentityRateLimit.js.map +1 -1
- package/build/dist/Server/Services/AIRunService.js +14 -1
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/BillingPaymentMethodService.js +71 -21
- package/build/dist/Server/Services/BillingPaymentMethodService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +210 -22
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceInstanceService.js +66 -0
- package/build/dist/Server/Services/CloudResourceInstanceService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +58 -13
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/ExceptionAggregationService.js +1 -0
- package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
- package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js +9 -0
- package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js.map +1 -0
- package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +7 -0
- package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +16 -0
- package/build/dist/Server/Services/Index.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/LogAggregationService.js +1 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricAggregationService.js +1 -0
- package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MobilePasskeyLoginService.js +137 -0
- package/build/dist/Server/Services/MobilePasskeyLoginService.js.map +1 -0
- package/build/dist/Server/Services/MonitorService.js +34 -1
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +167 -30
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +394 -38
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +142 -2
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.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/OpenTelemetryIngestService.js +28 -13
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/PayAsYouGoBillingService.js +297 -0
- package/build/dist/Server/Services/PayAsYouGoBillingService.js.map +1 -0
- package/build/dist/Server/Services/ProjectService.js +38 -2
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionInstanceService.js +66 -0
- package/build/dist/Server/Services/ServerlessFunctionInstanceService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +85 -28
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js +61 -10
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryUsageBillingService.js +62 -5
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +5 -4
- package/build/dist/Server/Services/TraceAggregationService.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/UserWebAuthnService.js +345 -113
- package/build/dist/Server/Services/UserWebAuthnService.js.map +1 -1
- package/build/dist/Server/Services/VMwareResourceService.js +395 -0
- package/build/dist/Server/Services/VMwareResourceService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterFeedService.js +89 -0
- package/build/dist/Server/Services/VMwareVCenterFeedService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js +197 -0
- package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterLabelRuleService.js +13 -0
- package/build/dist/Server/Services/VMwareVCenterLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js +214 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleService.js +13 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerTeamService.js +129 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerUserService.js +122 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/VMwareVCenterService.js +533 -0
- package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -0
- package/build/dist/Server/Services/WorkflowVariableService.js +169 -0
- package/build/dist/Server/Services/WorkflowVariableService.js.map +1 -1
- package/build/dist/Server/Types/Billing/MeteredPlan/ActiveMonitoringMeteredPlan.js +12 -1
- package/build/dist/Server/Types/Billing/MeteredPlan/ActiveMonitoringMeteredPlan.js.map +1 -1
- package/build/dist/Server/Types/Billing/MeteredPlan/TelemetryMeteredPlan.js +25 -2
- package/build/dist/Server/Types/Billing/MeteredPlan/TelemetryMeteredPlan.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/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/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubAgentTaskTrigger.js +275 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubAgentTaskTrigger.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubCommandAuthorizer.js +226 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubCommandAuthorizer.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubCommandParser.js +297 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubCommandParser.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubConversation.js +582 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubConversation.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubReplyComposer.js +275 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubReplyComposer.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubRunReply.js +365 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubRunReply.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubWebhookEvents.js +103 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubWebhookEvents.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubWebhookHandler.js +661 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubWebhookHandler.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +166 -18
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +99 -15
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +12 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +20 -2
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +31 -2
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -1
- package/build/dist/Server/Utils/LogRedaction.js +2 -1
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +58 -35
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.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 +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +382 -36
- 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/MonitorMaintenanceSuppression.js +12 -4
- package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +5 -3
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +22 -9
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +1 -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/SeriesResourceLabels.js +21 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +21 -6
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
- package/build/dist/Server/Utils/ResourceFeed/ResourceFeedUtil.js +3 -3
- package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js +9 -9
- package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js +92 -71
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +428 -143
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js +376 -0
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +14 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +206 -14
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/VMwareSnapshotScan.js +933 -0
- package/build/dist/Server/Utils/Telemetry/VMwareSnapshotScan.js.map +1 -0
- package/build/dist/Types/AI/CodeFixTaskContext.js +40 -0
- package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -1
- package/build/dist/Types/AI/CodeFixTaskType.js +57 -0
- package/build/dist/Types/AI/CodeFixTaskType.js.map +1 -1
- package/build/dist/Types/Accounts/AccountsLanguage.js +1 -0
- package/build/dist/Types/Accounts/AccountsLanguage.js.map +1 -1
- package/build/dist/Types/AdminDashboard/AdminDashboardLanguage.js +1 -0
- package/build/dist/Types/AdminDashboard/AdminDashboardLanguage.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/Cloud/CloudPlatform.js +277 -0
- package/build/dist/Types/Cloud/CloudPlatform.js.map +1 -0
- package/build/dist/Types/CodeRepository/GitHubCommand.js +52 -0
- package/build/dist/Types/CodeRepository/GitHubCommand.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardVMwareHostListComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardVMwareHostListComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardVMwareVirtualMachineListComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardVMwareVirtualMachineListComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardLanguage.js +1 -0
- package/build/dist/Types/Dashboard/DashboardLanguage.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardTemplates.js +286 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.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/Docs/DocsLanguage.js +1 -0
- package/build/dist/Types/Docs/DocsLanguage.js.map +1 -1
- package/build/dist/Types/Exception/EgressGuardException.js +59 -0
- package/build/dist/Types/Exception/EgressGuardException.js.map +1 -0
- 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 +13 -0
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +1 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +61 -18
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepMetricViewConfigUtil.js +1 -0
- package/build/dist/Types/Monitor/MonitorStepMetricViewConfigUtil.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepVMwareMonitor.js +71 -0
- package/build/dist/Types/Monitor/MonitorStepVMwareMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorTemplateSyncField.js +211 -0
- package/build/dist/Types/Monitor/MonitorTemplateSyncField.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorType.js +23 -0
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +28 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +2 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +120 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -1
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +60 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
- package/build/dist/Types/Monitor/VMwareAlertTemplates.js +775 -0
- package/build/dist/Types/Monitor/VMwareAlertTemplates.js.map +1 -0
- package/build/dist/Types/Monitor/VMwareMetricCatalog.js +799 -0
- package/build/dist/Types/Monitor/VMwareMetricCatalog.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/OnCallDutyPolicy/ScheduleShiftUtil.js +25 -0
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js +5 -0
- package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js.map +1 -1
- package/build/dist/Types/Password.js +63 -5
- package/build/dist/Types/Password.js.map +1 -1
- package/build/dist/Types/Permission.js +234 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Probe/RequestFailedDetails.js +7 -0
- package/build/dist/Types/Probe/RequestFailedDetails.js.map +1 -1
- package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js +2 -0
- package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.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/StatusPage/StatusPageLanguage.js +1 -0
- package/build/dist/Types/StatusPage/StatusPageLanguage.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityType.js +21 -0
- package/build/dist/Types/Telemetry/EntityType.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/ServiceType.js +1 -0
- package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
- package/build/dist/UI/Components/Breadcrumbs/Breadcrumbs.js +2 -2
- package/build/dist/UI/Components/Breadcrumbs/Breadcrumbs.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/Calendar/Calendar.js +24 -4
- package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +9 -2
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- 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/Forms/BasicForm.js +28 -3
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +1 -1
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +10 -3
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +89 -6
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +5 -6
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +14 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +37 -8
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/LabelRule/ImportLabelRulesModal.js +228 -0
- package/build/dist/UI/Components/LabelRule/ImportLabelRulesModal.js.map +1 -0
- package/build/dist/UI/Components/LabelRule/LabelRuleTable.js +102 -0
- package/build/dist/UI/Components/LabelRule/LabelRuleTable.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +15 -2
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ModelTable.js +13 -5
- package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +14 -15
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +2 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +33 -4
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/UI/Utils/DashboardStackingLayers.js +44 -0
- package/build/dist/UI/Utils/DashboardStackingLayers.js.map +1 -0
- package/build/dist/UI/Utils/LabelRuleImportExport.js +195 -0
- package/build/dist/UI/Utils/LabelRuleImportExport.js.map +1 -0
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +4 -4
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/TelemetryService.js +3 -2
- package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
- package/build/dist/UI/Utils/UseDashboardGridDnd.js +2 -1
- package/build/dist/UI/Utils/UseDashboardGridDnd.js.map +1 -1
- package/build/dist/UI/Utils/UserEmailRegistrationStatus.js +21 -4
- package/build/dist/UI/Utils/UserEmailRegistrationStatus.js.map +1 -1
- package/build/dist/UI/Utils/WebAuthn.js +121 -0
- package/build/dist/UI/Utils/WebAuthn.js.map +1 -0
- package/build/dist/Utils/API.js +29 -0
- 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/Components/DashboardVMwareHostListComponent.js +33 -0
- package/build/dist/Utils/Dashboard/Components/DashboardVMwareHostListComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardVMwareResourceListShared.js +54 -0
- package/build/dist/Utils/Dashboard/Components/DashboardVMwareResourceListShared.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardVMwareVirtualMachineListComponent.js +60 -0
- package/build/dist/Utils/Dashboard/Components/DashboardVMwareVirtualMachineListComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +8 -0
- package/build/dist/Utils/Dashboard/Components/Index.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/LabelRuleImportExport.js +356 -0
- package/build/dist/Utils/LabelRuleImportExport.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/MonitorTemplateSyncUtil.js +110 -0
- package/build/dist/Utils/Monitor/MonitorTemplateSyncUtil.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 +6 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -1
- package/build/dist/Utils/Telemetry/CloudInstanceIdentity.js +88 -0
- package/build/dist/Utils/Telemetry/CloudInstanceIdentity.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityKey.js +15 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityRelationship.js +13 -0
- package/build/dist/Utils/Telemetry/EntityRelationship.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
- package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +0 -399
|
@@ -4,6 +4,8 @@ import DatabaseService from "./DatabaseService";
|
|
|
4
4
|
import Model from "../../Models/DatabaseModels/UserWebAuthn";
|
|
5
5
|
import UserService from "./UserService";
|
|
6
6
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
7
|
+
import Exception from "../../Types/Exception/Exception";
|
|
8
|
+
import Hostname from "../../Types/API/Hostname";
|
|
7
9
|
import User from "../../Models/DatabaseModels/User";
|
|
8
10
|
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
9
11
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
@@ -16,9 +18,260 @@ import {
|
|
|
16
18
|
import { Host, HttpProtocol } from "../EnvironmentConfig";
|
|
17
19
|
import ObjectID from "../../Types/ObjectID";
|
|
18
20
|
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
19
|
-
import
|
|
21
|
+
import Redis, { ClientType } from "../Infrastructure/Redis";
|
|
22
|
+
import DatabaseNotConnectedException from "../../Types/Exception/DatabaseNotConnectedException";
|
|
23
|
+
import { randomBytes } from "crypto";
|
|
24
|
+
import { URL } from "url";
|
|
20
25
|
|
|
21
26
|
const WEBAUTHN_CHALLENGE_TTL_MINUTES: number = 5;
|
|
27
|
+
const AUTHENTICATION_CHALLENGE_PREFIX: string = "webauthn-security-key-login-";
|
|
28
|
+
const REGISTRATION_CHALLENGE_PREFIX: string = "webauthn-registration-";
|
|
29
|
+
const PASSKEY_CHALLENGE_PREFIX: string = "webauthn-passkey-login-";
|
|
30
|
+
|
|
31
|
+
interface RegistrationChallenge {
|
|
32
|
+
challenge: string;
|
|
33
|
+
requireUserVerification: boolean;
|
|
34
|
+
isPasskey?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
* One answer for both ways of having no security key to offer, because the
|
|
39
|
+
* route that asks is anonymous.
|
|
40
|
+
*
|
|
41
|
+
* `generateAuthenticationOptions` is reached by POSTing an email address and
|
|
42
|
+
* nothing else. It used to answer "User not found" for an address nobody has
|
|
43
|
+
* registered and "No WebAuthn credentials found for this user" for one that
|
|
44
|
+
* exists but has no key -- two distinguishable replies, which together are a
|
|
45
|
+
* free account-existence oracle for anyone who can send a request, and a
|
|
46
|
+
* second oracle telling them which of those accounts is protected by hardware.
|
|
47
|
+
*
|
|
48
|
+
* Every other door on this surface already refuses to say that much: the login
|
|
49
|
+
* routes deliberately do not reveal which half of a credential was wrong, and
|
|
50
|
+
* IdentityRateLimit answers identically for a real address and an invented
|
|
51
|
+
* one specifically so that being throttled does not give back the enumeration
|
|
52
|
+
* the handlers withhold. This route was the exception.
|
|
53
|
+
*
|
|
54
|
+
* Nothing legitimate is lost. A real user only reaches this after signing in
|
|
55
|
+
* with their password, from a list of their OWN registered keys returned by
|
|
56
|
+
* /login -- so they cannot arrive here with an account that has none, and the
|
|
57
|
+
* message they would never see is not worth an oracle to everyone else.
|
|
58
|
+
*/
|
|
59
|
+
const NO_SECURITY_KEY_AVAILABLE: string =
|
|
60
|
+
"No security key is available for this account.";
|
|
61
|
+
|
|
62
|
+
/*
|
|
63
|
+
* How much a security key is asked to prove about the person holding it.
|
|
64
|
+
*
|
|
65
|
+
* "preferred" means: verify the user -- a fingerprint, a face, a PIN, a system
|
|
66
|
+
* password -- IF you can, and go ahead without it if you cannot. That second
|
|
67
|
+
* clause is the entire reason to choose the value over "required", and it is
|
|
68
|
+
* exercised constantly by ordinary hardware:
|
|
69
|
+
*
|
|
70
|
+
* - a MacBook running folded shut on an external display ("clamshell") has
|
|
71
|
+
* no reachable Touch ID sensor;
|
|
72
|
+
* - a plain USB security key with no PIN set has nothing to verify with;
|
|
73
|
+
* - Windows Hello is unavailable on a desktop with no camera or reader.
|
|
74
|
+
*
|
|
75
|
+
* In each case the browser returns a perfectly good credential with the UV bit
|
|
76
|
+
* in the authenticator data left CLEAR, exactly as we asked it to.
|
|
77
|
+
*/
|
|
78
|
+
type WebAuthnUserVerification = "required" | "preferred" | "discouraged";
|
|
79
|
+
|
|
80
|
+
const WEBAUTHN_USER_VERIFICATION: WebAuthnUserVerification = "preferred";
|
|
81
|
+
|
|
82
|
+
/*
|
|
83
|
+
* The other half of that policy, and the half that was missing.
|
|
84
|
+
*
|
|
85
|
+
* `verifyRegistrationResponse` and `verifyAuthenticationResponse` both default
|
|
86
|
+
* `requireUserVerification` to TRUE. Left unset, they therefore REJECT the
|
|
87
|
+
* very responses the options above told the authenticator were acceptable --
|
|
88
|
+
* so a user in clamshell mode got "User verification was required, but user
|
|
89
|
+
* could not be verified" thrown out of the library and rendered as an
|
|
90
|
+
* unexplained "Server Error" (issue #3652). Registration was where it was
|
|
91
|
+
* reported, but the identical default sits on the authentication call, so a
|
|
92
|
+
* key enrolled at a desk also failed to SIGN IN from the same laptop later.
|
|
93
|
+
*
|
|
94
|
+
* DERIVED from the requested policy rather than written as a bare `false` in
|
|
95
|
+
* two places, because the drift between what we asked for and what we then
|
|
96
|
+
* demanded IS the bug. Tying both to one constant means raising the policy to
|
|
97
|
+
* "required" cannot leave verification behind, and relaxing it cannot leave
|
|
98
|
+
* verification ahead. The comparison goes through a function taking the union
|
|
99
|
+
* type because TypeScript narrows a `const` to the literal it was initialised
|
|
100
|
+
* with and then rejects the comparison outright -- which would push this back
|
|
101
|
+
* to a hand-written `false` and reopen the drift.
|
|
102
|
+
*
|
|
103
|
+
* Relaxing this does not weaken the account. A security key is OneUptime's
|
|
104
|
+
* SECOND factor: the password has already been proven by the time any of this
|
|
105
|
+
* runs (see the verifyWebAuthn branch in
|
|
106
|
+
* App/FeatureSet/Identity/API/Authentication.ts), so user verification would
|
|
107
|
+
* be buying a second proof of the same person rather than a second factor.
|
|
108
|
+
* What it would cost is real -- every authenticator that cannot verify becomes
|
|
109
|
+
* unusable, and the user is locked out by hardware rather than by policy.
|
|
110
|
+
*/
|
|
111
|
+
type RequiresUserVerificationFunction = (
|
|
112
|
+
policy: WebAuthnUserVerification,
|
|
113
|
+
) => boolean;
|
|
114
|
+
|
|
115
|
+
const requiresUserVerification: RequiresUserVerificationFunction = (
|
|
116
|
+
policy: WebAuthnUserVerification,
|
|
117
|
+
): boolean => {
|
|
118
|
+
return policy === "required";
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const WEBAUTHN_REQUIRE_USER_VERIFICATION: boolean = requiresUserVerification(
|
|
122
|
+
WEBAUTHN_USER_VERIFICATION,
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
/*
|
|
126
|
+
* Everything @simplewebauthn/server refuses, it refuses by throwing a plain
|
|
127
|
+
* `Error` rather than one of our `Exception`s -- and the last-resort handler
|
|
128
|
+
* in Common/Server/Utils/StartServer.ts has no branch for a plain Error. It
|
|
129
|
+
* falls through to `res.status(500).send({ error: "Server Error" })`, which
|
|
130
|
+
* DISCARDS the message.
|
|
131
|
+
*
|
|
132
|
+
* That is the other half of what issue #3652 reported. The user saw an
|
|
133
|
+
* unexplained "Server Error"; the sentence that actually says what went wrong
|
|
134
|
+
* ("User verification was required, but user could not be verified") only ever
|
|
135
|
+
* reached the server log, which a hosted user cannot read at all and a
|
|
136
|
+
* self-hoster has to go looking for. Every WebAuthn failure looked identical
|
|
137
|
+
* from the browser: a misconfigured reverse proxy serving a different origin
|
|
138
|
+
* than HOST claims, a challenge that timed out while the user hunted for their
|
|
139
|
+
* key, and a genuinely bad credential were one indistinguishable 500.
|
|
140
|
+
*
|
|
141
|
+
* The messages are safe to show. They name the origin, the relying party id or
|
|
142
|
+
* the challenge THIS SERVER expected -- all of which the browser making the
|
|
143
|
+
* request already knows -- and for a self-hoster the origin mismatch is the
|
|
144
|
+
* single most useful thing the product can say.
|
|
145
|
+
*
|
|
146
|
+
* Exceptions we raised ourselves pass straight through, so the specific
|
|
147
|
+
* wording of the challenge errors below is not flattened into the generic one.
|
|
148
|
+
*/
|
|
149
|
+
type VerifyWebAuthnResponseFunction = (
|
|
150
|
+
verify: () => Promise<any>,
|
|
151
|
+
) => Promise<any>;
|
|
152
|
+
|
|
153
|
+
const explainVerificationFailure: VerifyWebAuthnResponseFunction = async (
|
|
154
|
+
verify: () => Promise<any>,
|
|
155
|
+
): Promise<any> => {
|
|
156
|
+
try {
|
|
157
|
+
return await verify();
|
|
158
|
+
} catch (err) {
|
|
159
|
+
if (err instanceof Exception) {
|
|
160
|
+
throw err;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
throw new BadDataException(
|
|
164
|
+
err instanceof Error && err.message
|
|
165
|
+
? err.message
|
|
166
|
+
: "Could not verify this security key.",
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/*
|
|
172
|
+
* The relying party id, which is NOT the origin and must not be written as if
|
|
173
|
+
* it were.
|
|
174
|
+
*
|
|
175
|
+
* `expectedOrigin` is a full origin and MUST carry the port: a browser on
|
|
176
|
+
* https://oneuptime.example.com:8443 puts exactly that in its client data. The
|
|
177
|
+
* RP ID is a bare registrable domain and must NOT -- the spec defines it as a
|
|
178
|
+
* domain string, and a browser handed "oneuptime.example.com:8443" rejects the
|
|
179
|
+
* call outright with a SecurityError before any authenticator is asked
|
|
180
|
+
* anything. The two are built from the same HOST here, so they were the same
|
|
181
|
+
* string, and one of them was wrong.
|
|
182
|
+
*
|
|
183
|
+
* HOST is whatever the operator put in the environment (`Common/Server/EnvironmentConfig.ts`),
|
|
184
|
+
* and for a self-hosted instance not sitting on 80/443 that is routinely
|
|
185
|
+
* `host:port` -- which made WebAuthn unusable on those deployments rather than
|
|
186
|
+
* merely awkward. Nothing is invalidated by fixing it: on exactly the
|
|
187
|
+
* deployments this changes, the browser refused to create a credential at all,
|
|
188
|
+
* so there are none to invalidate. Where HOST carries no port, this is the
|
|
189
|
+
* identity function and no existing credential moves.
|
|
190
|
+
*
|
|
191
|
+
* `fromAuthority` rather than `fromString`: it is the one that understands
|
|
192
|
+
* bracketed IPv6 literals and userinfo instead of splitting on the first colon
|
|
193
|
+
* and turning "[::1]:8443" into a host of "[".
|
|
194
|
+
*/
|
|
195
|
+
type WebAuthnRelyingPartyIdFunction = () => string;
|
|
196
|
+
|
|
197
|
+
const webAuthnRelyingPartyId: WebAuthnRelyingPartyIdFunction = (): string => {
|
|
198
|
+
return Hostname.fromAuthority(Host.toString()).hostname;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/*
|
|
202
|
+
* The transports a stored credential reported at registration, back out of the
|
|
203
|
+
* text column and into the shape `allowCredentials` wants.
|
|
204
|
+
*
|
|
205
|
+
* Spelled out locally rather than imported as the library's
|
|
206
|
+
* `AuthenticatorTransportFuture`, for the same reason the user-verification
|
|
207
|
+
* policy above is: the type has to hold when Common's jest config swaps the
|
|
208
|
+
* whole package for a stub.
|
|
209
|
+
*
|
|
210
|
+
* Deliberately forgiving, and it returns UNDEFINED rather than an empty array
|
|
211
|
+
* when it has nothing to say. Every credential registered before this change
|
|
212
|
+
* holds the literal "[]", and there is a difference between telling the
|
|
213
|
+
* browser "this key is reachable by no transport" and not telling it anything:
|
|
214
|
+
* the first is a hint that excludes every option, the second is what those
|
|
215
|
+
* credentials have always sent. An unreadable value costs the user a hint,
|
|
216
|
+
* never their sign-in.
|
|
217
|
+
*
|
|
218
|
+
* Filtering to the known set happens on READ, not on write, so a transport
|
|
219
|
+
* some future browser invents is still recorded faithfully in the column and
|
|
220
|
+
* only the hint drops it.
|
|
221
|
+
*/
|
|
222
|
+
type WebAuthnTransport =
|
|
223
|
+
| "ble"
|
|
224
|
+
| "cable"
|
|
225
|
+
| "hybrid"
|
|
226
|
+
| "internal"
|
|
227
|
+
| "nfc"
|
|
228
|
+
| "smart-card"
|
|
229
|
+
| "usb";
|
|
230
|
+
|
|
231
|
+
const KNOWN_WEBAUTHN_TRANSPORTS: Array<string> = [
|
|
232
|
+
"ble",
|
|
233
|
+
"cable",
|
|
234
|
+
"hybrid",
|
|
235
|
+
"internal",
|
|
236
|
+
"nfc",
|
|
237
|
+
"smart-card",
|
|
238
|
+
"usb",
|
|
239
|
+
];
|
|
240
|
+
|
|
241
|
+
type ParseTransportsFunction = (
|
|
242
|
+
stored: string | undefined,
|
|
243
|
+
) => Array<WebAuthnTransport> | undefined;
|
|
244
|
+
|
|
245
|
+
const parseStoredTransports: ParseTransportsFunction = (
|
|
246
|
+
stored: string | undefined,
|
|
247
|
+
): Array<WebAuthnTransport> | undefined => {
|
|
248
|
+
if (!stored) {
|
|
249
|
+
return undefined;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
let parsed: unknown = undefined;
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
parsed = JSON.parse(stored);
|
|
256
|
+
} catch {
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (!Array.isArray(parsed)) {
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const transports: Array<WebAuthnTransport> = parsed.filter(
|
|
265
|
+
(transport: unknown) => {
|
|
266
|
+
return (
|
|
267
|
+
typeof transport === "string" &&
|
|
268
|
+
KNOWN_WEBAUTHN_TRANSPORTS.includes(transport)
|
|
269
|
+
);
|
|
270
|
+
},
|
|
271
|
+
) as Array<WebAuthnTransport>;
|
|
272
|
+
|
|
273
|
+
return transports.length > 0 ? transports : undefined;
|
|
274
|
+
};
|
|
22
275
|
|
|
23
276
|
export class Service extends DatabaseService<Model> {
|
|
24
277
|
public constructor() {
|
|
@@ -28,6 +281,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
28
281
|
@CaptureSpan()
|
|
29
282
|
public async generateRegistrationOptions(data: {
|
|
30
283
|
userId: ObjectID;
|
|
284
|
+
isPasskey?: boolean;
|
|
31
285
|
}): Promise<{ options: any; challenge: string }> {
|
|
32
286
|
const user: User | null = await UserService.findOneById({
|
|
33
287
|
id: data.userId,
|
|
@@ -55,6 +309,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
55
309
|
},
|
|
56
310
|
select: {
|
|
57
311
|
credentialId: true,
|
|
312
|
+
transports: true,
|
|
58
313
|
},
|
|
59
314
|
limit: LIMIT_PER_PROJECT,
|
|
60
315
|
skip: 0,
|
|
@@ -65,7 +320,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
65
320
|
|
|
66
321
|
const options: any = await generateRegistrationOptions({
|
|
67
322
|
rpName: "OneUptime",
|
|
68
|
-
rpID:
|
|
323
|
+
rpID: this.getRelyingParty().rpID,
|
|
69
324
|
userID: new Uint8Array(Buffer.from(data.userId.toString())),
|
|
70
325
|
userName: user.email.toString(),
|
|
71
326
|
userDisplayName: user.name ? user.name.toString() : user.email.toString(),
|
|
@@ -75,47 +330,35 @@ export class Service extends DatabaseService<Model> {
|
|
|
75
330
|
return cred.credentialId;
|
|
76
331
|
})
|
|
77
332
|
.map((cred: Model) => {
|
|
333
|
+
/* Same hint as allowCredentials carries; see the note there. */
|
|
334
|
+
const transports: Array<WebAuthnTransport> | undefined =
|
|
335
|
+
parseStoredTransports(cred.transports);
|
|
78
336
|
return {
|
|
79
337
|
id: cred.credentialId!,
|
|
80
338
|
type: "public-key",
|
|
339
|
+
...(transports ? { transports } : {}),
|
|
81
340
|
};
|
|
82
341
|
}),
|
|
83
342
|
authenticatorSelection: {
|
|
84
|
-
residentKey: "discouraged",
|
|
85
|
-
userVerification:
|
|
343
|
+
residentKey: data.isPasskey === true ? "required" : "discouraged",
|
|
344
|
+
userVerification:
|
|
345
|
+
data.isPasskey === true ? "required" : WEBAUTHN_USER_VERIFICATION,
|
|
86
346
|
},
|
|
87
347
|
});
|
|
88
348
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Store the challenge server-side so verification uses a trusted value
|
|
106
|
-
await UserService.updateOneById({
|
|
107
|
-
id: data.userId,
|
|
108
|
-
data: {
|
|
109
|
-
webauthnChallenge: options.challenge,
|
|
110
|
-
webauthnChallengeExpiresAt: OneUptimeDate.addRemoveMinutes(
|
|
111
|
-
OneUptimeDate.getCurrentDate(),
|
|
112
|
-
WEBAUTHN_CHALLENGE_TTL_MINUTES,
|
|
113
|
-
),
|
|
114
|
-
},
|
|
115
|
-
props: {
|
|
116
|
-
isRoot: true,
|
|
117
|
-
},
|
|
118
|
-
});
|
|
349
|
+
/*
|
|
350
|
+
* SimpleWebAuthn already returns base64url JSON. Preserve the exact
|
|
351
|
+
* challenge, and bind the verification requirement to server-side state.
|
|
352
|
+
*/
|
|
353
|
+
await this.storeChallenge(
|
|
354
|
+
`${REGISTRATION_CHALLENGE_PREFIX}${data.userId.toString()}`,
|
|
355
|
+
JSON.stringify({
|
|
356
|
+
challenge: options.challenge,
|
|
357
|
+
requireUserVerification:
|
|
358
|
+
data.isPasskey === true || WEBAUTHN_REQUIRE_USER_VERIFICATION,
|
|
359
|
+
isPasskey: data.isPasskey === true,
|
|
360
|
+
}),
|
|
361
|
+
);
|
|
119
362
|
|
|
120
363
|
return {
|
|
121
364
|
options: options as any,
|
|
@@ -133,18 +376,27 @@ export class Service extends DatabaseService<Model> {
|
|
|
133
376
|
throw new BadDataException("User ID not found in request");
|
|
134
377
|
}
|
|
135
378
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
379
|
+
const storedChallenge: RegistrationChallenge = JSON.parse(
|
|
380
|
+
await this.consumeChallenge(
|
|
381
|
+
`${REGISTRATION_CHALLENGE_PREFIX}${data.props.userId.toString()}`,
|
|
382
|
+
),
|
|
383
|
+
) as RegistrationChallenge;
|
|
140
384
|
|
|
141
|
-
|
|
385
|
+
if (
|
|
386
|
+
!storedChallenge.challenge ||
|
|
387
|
+
typeof storedChallenge.requireUserVerification !== "boolean"
|
|
388
|
+
) {
|
|
389
|
+
throw new BadDataException("Invalid registration challenge");
|
|
390
|
+
}
|
|
142
391
|
|
|
143
|
-
const verification: any = await
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
392
|
+
const verification: any = await explainVerificationFailure(() => {
|
|
393
|
+
return verifyRegistrationResponse({
|
|
394
|
+
response: data.credential,
|
|
395
|
+
expectedChallenge: storedChallenge.challenge,
|
|
396
|
+
expectedOrigin: this.getRelyingParty().origin,
|
|
397
|
+
expectedRPID: this.getRelyingParty().rpID,
|
|
398
|
+
requireUserVerification: storedChallenge.requireUserVerification,
|
|
399
|
+
});
|
|
148
400
|
});
|
|
149
401
|
|
|
150
402
|
if (!verification.verified) {
|
|
@@ -157,6 +409,15 @@ export class Service extends DatabaseService<Model> {
|
|
|
157
409
|
throw new BadDataException("Registration info not found");
|
|
158
410
|
}
|
|
159
411
|
|
|
412
|
+
if (
|
|
413
|
+
storedChallenge.requireUserVerification &&
|
|
414
|
+
!registrationInfo.userVerified
|
|
415
|
+
) {
|
|
416
|
+
throw new BadDataException(
|
|
417
|
+
"Passkey registration requires user verification",
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
|
|
160
421
|
// Save the credential
|
|
161
422
|
const userWebAuthn: Model = Model.fromJSON(
|
|
162
423
|
{
|
|
@@ -165,9 +426,46 @@ export class Service extends DatabaseService<Model> {
|
|
|
165
426
|
publicKey: Buffer.from(registrationInfo.credential.publicKey).toString(
|
|
166
427
|
"base64",
|
|
167
428
|
),
|
|
168
|
-
|
|
169
|
-
|
|
429
|
+
/*
|
|
430
|
+
* From the authenticator, not hard-coded.
|
|
431
|
+
*
|
|
432
|
+
* The counter used to be written as "0" regardless. Most platform
|
|
433
|
+
* authenticators do report 0 -- a passkey synced between devices
|
|
434
|
+
* cannot keep a meaningful count -- but a discrete key that has been
|
|
435
|
+
* used elsewhere arrives with a real one, and pinning it to 0 threw
|
|
436
|
+
* that away. `verifyAuthenticationResponse` only compares counters
|
|
437
|
+
* when at least one side is above zero, so the discarded value was
|
|
438
|
+
* precisely the clone detection this credential was eligible for:
|
|
439
|
+
* a key registered at count 40 and a clone of it replaying count 12
|
|
440
|
+
* both looked fine against a stored 0.
|
|
441
|
+
*
|
|
442
|
+
* The trade is not free, and the tail is worth naming: an
|
|
443
|
+
* authenticator that reports the SAME counter at registration and at
|
|
444
|
+
* its first assertion now fails that comparison, where a stored 0
|
|
445
|
+
* would have waved it through. A spec-compliant key increments on
|
|
446
|
+
* every assertion, so this should not happen -- but if it does, the
|
|
447
|
+
* key is unusable and the way back in is a backup code (minted at
|
|
448
|
+
* enrolment, see UserWebAuthnAPI) followed by registering it again.
|
|
449
|
+
* The alternative is to keep discarding the counter and keep the
|
|
450
|
+
* clone detection permanently off, which is the worse default.
|
|
451
|
+
*
|
|
452
|
+
* Transports were likewise always "[]". They are the browser's hint
|
|
453
|
+
* about HOW to reach this key -- USB, NFC, the platform itself -- and
|
|
454
|
+
* with none recorded every sign-in prompt has to offer all of them.
|
|
455
|
+
*/
|
|
456
|
+
counter:
|
|
457
|
+
typeof registrationInfo.credential.counter === "number"
|
|
458
|
+
? registrationInfo.credential.counter.toString()
|
|
459
|
+
: "0",
|
|
460
|
+
transports: JSON.stringify(
|
|
461
|
+
registrationInfo.credential.transports || [],
|
|
462
|
+
),
|
|
170
463
|
isVerified: true,
|
|
464
|
+
/*
|
|
465
|
+
* Use only the server-bound ceremony purpose, never a client assertion.
|
|
466
|
+
* Challenges created just before an upgrade retain the legacy unknown value.
|
|
467
|
+
*/
|
|
468
|
+
isPasskey: storedChallenge.isPasskey,
|
|
171
469
|
userId: data.props.userId,
|
|
172
470
|
},
|
|
173
471
|
Model,
|
|
@@ -175,14 +473,18 @@ export class Service extends DatabaseService<Model> {
|
|
|
175
473
|
|
|
176
474
|
await this.create({
|
|
177
475
|
data: userWebAuthn,
|
|
178
|
-
|
|
476
|
+
/*
|
|
477
|
+
* The credential and its purpose have been verified above. The purpose is
|
|
478
|
+
* read-only through CRUD; only this verified registration path writes it.
|
|
479
|
+
*/
|
|
480
|
+
props: { ...data.props, isRoot: true },
|
|
179
481
|
});
|
|
180
482
|
}
|
|
181
483
|
|
|
182
484
|
@CaptureSpan()
|
|
183
485
|
public async generateAuthenticationOptions(data: {
|
|
184
486
|
email: string;
|
|
185
|
-
}): Promise<{ options: any; challenge: string
|
|
487
|
+
}): Promise<{ options: any; challenge: string }> {
|
|
186
488
|
const user: User | null = await UserService.findOneBy({
|
|
187
489
|
query: { email: data.email },
|
|
188
490
|
select: {
|
|
@@ -194,7 +496,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
194
496
|
});
|
|
195
497
|
|
|
196
498
|
if (!user) {
|
|
197
|
-
throw new BadDataException(
|
|
499
|
+
throw new BadDataException(NO_SECURITY_KEY_AVAILABLE);
|
|
198
500
|
}
|
|
199
501
|
|
|
200
502
|
// Get user's WebAuthn credentials
|
|
@@ -205,6 +507,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
205
507
|
},
|
|
206
508
|
select: {
|
|
207
509
|
credentialId: true,
|
|
510
|
+
transports: true,
|
|
208
511
|
},
|
|
209
512
|
limit: LIMIT_PER_PROJECT,
|
|
210
513
|
skip: 0,
|
|
@@ -214,43 +517,62 @@ export class Service extends DatabaseService<Model> {
|
|
|
214
517
|
});
|
|
215
518
|
|
|
216
519
|
if (credentials.length === 0) {
|
|
217
|
-
throw new BadDataException(
|
|
520
|
+
throw new BadDataException(NO_SECURITY_KEY_AVAILABLE);
|
|
218
521
|
}
|
|
219
522
|
|
|
220
523
|
const options: any = await generateAuthenticationOptions({
|
|
221
|
-
rpID:
|
|
524
|
+
rpID: this.getRelyingParty().rpID,
|
|
222
525
|
allowCredentials: credentials.map((cred: Model) => {
|
|
526
|
+
/*
|
|
527
|
+
* Recording transports at registration buys nothing unless they are
|
|
528
|
+
* handed back here: this is the only place the browser reads them.
|
|
529
|
+
* With the hint, a key that says "usb" prompts for a USB key rather
|
|
530
|
+
* than opening the whole carousel of ways a credential might be
|
|
531
|
+
* reachable. `generateAuthenticationOptions` copies unknown fields
|
|
532
|
+
* straight through onto the descriptor, and Login.tsx rewrites only
|
|
533
|
+
* `id`, so the array survives to navigator.credentials.get().
|
|
534
|
+
*
|
|
535
|
+
* SPREAD rather than `transports: undefined`, so a credential with no
|
|
536
|
+
* hint carries no `transports` member at all. The two are not the
|
|
537
|
+
* same to a browser -- an empty array is a hint that excludes every
|
|
538
|
+
* transport, and Chromium filters on the hint when it is present, so
|
|
539
|
+
* an empty one could hide a key that works perfectly well.
|
|
540
|
+
*/
|
|
541
|
+
const transports: Array<WebAuthnTransport> | undefined =
|
|
542
|
+
parseStoredTransports(cred.transports);
|
|
223
543
|
return {
|
|
224
544
|
id: cred.credentialId!,
|
|
225
545
|
type: "public-key",
|
|
546
|
+
...(transports ? { transports } : {}),
|
|
226
547
|
};
|
|
227
548
|
}),
|
|
228
|
-
userVerification:
|
|
549
|
+
userVerification: WEBAUTHN_USER_VERIFICATION,
|
|
229
550
|
});
|
|
230
551
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
// Store the challenge server-side so verification uses a trusted value
|
|
236
|
-
await UserService.updateOneById({
|
|
237
|
-
id: user.id!,
|
|
238
|
-
data: {
|
|
239
|
-
webauthnChallenge: options.challenge,
|
|
240
|
-
webauthnChallengeExpiresAt: OneUptimeDate.addRemoveMinutes(
|
|
241
|
-
OneUptimeDate.getCurrentDate(),
|
|
242
|
-
WEBAUTHN_CHALLENGE_TTL_MINUTES,
|
|
243
|
-
),
|
|
244
|
-
},
|
|
245
|
-
props: {
|
|
246
|
-
isRoot: true,
|
|
247
|
-
},
|
|
248
|
-
});
|
|
552
|
+
await this.storeChallenge(
|
|
553
|
+
`${AUTHENTICATION_CHALLENGE_PREFIX}${user.id!.toString()}`,
|
|
554
|
+
options.challenge,
|
|
555
|
+
);
|
|
249
556
|
|
|
557
|
+
/*
|
|
558
|
+
* The anonymous caller gets the ceremony and nothing else.
|
|
559
|
+
*
|
|
560
|
+
* This used to hand back `userId` too -- the account's real row id, to
|
|
561
|
+
* anybody who could name an email address with a key on it. Nothing ever
|
|
562
|
+
* read it: the browser posts the assertion to /verify-webauthn-auth along
|
|
563
|
+
* with the email and password again, and that route takes the user from
|
|
564
|
+
* the password it has just verified
|
|
565
|
+
* (App/FeatureSet/Identity/API/Authentication.ts), never from the body.
|
|
566
|
+
*
|
|
567
|
+
* So it was an identifier handed to strangers for free, on the one route
|
|
568
|
+
* that has just been made careful about what it tells them -- and it would
|
|
569
|
+
* have undone half of that: unifying the two refusals stops a caller
|
|
570
|
+
* learning whether an account exists, while a success that carries its
|
|
571
|
+
* internal id tells them rather more than that.
|
|
572
|
+
*/
|
|
250
573
|
return {
|
|
251
574
|
options: options as any,
|
|
252
575
|
challenge: options.challenge,
|
|
253
|
-
userId: user.id!.toString(),
|
|
254
576
|
};
|
|
255
577
|
}
|
|
256
578
|
|
|
@@ -260,8 +582,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
260
582
|
credential: any;
|
|
261
583
|
}): Promise<User> {
|
|
262
584
|
// Retrieve the challenge from the server-side store
|
|
263
|
-
const storedChallenge: string = await this.
|
|
264
|
-
new ObjectID(data.userId)
|
|
585
|
+
const storedChallenge: string = await this.consumeChallenge(
|
|
586
|
+
`${AUTHENTICATION_CHALLENGE_PREFIX}${new ObjectID(data.userId).toString()}`,
|
|
265
587
|
);
|
|
266
588
|
|
|
267
589
|
const user: User | null = await UserService.findOneById({
|
|
@@ -301,18 +623,19 @@ export class Service extends DatabaseService<Model> {
|
|
|
301
623
|
throw new BadDataException("Credential not found");
|
|
302
624
|
}
|
|
303
625
|
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
626
|
+
const verification: any = await explainVerificationFailure(() => {
|
|
627
|
+
return verifyAuthenticationResponse({
|
|
628
|
+
response: data.credential,
|
|
629
|
+
expectedChallenge: storedChallenge,
|
|
630
|
+
requireUserVerification: WEBAUTHN_REQUIRE_USER_VERIFICATION,
|
|
631
|
+
expectedOrigin: this.getRelyingParty().origin,
|
|
632
|
+
expectedRPID: this.getRelyingParty().rpID,
|
|
633
|
+
credential: {
|
|
634
|
+
id: dbCredential.credentialId!,
|
|
635
|
+
publicKey: Buffer.from(dbCredential.publicKey!, "base64"),
|
|
636
|
+
counter: parseInt(dbCredential.counter!),
|
|
637
|
+
} as any,
|
|
638
|
+
});
|
|
316
639
|
});
|
|
317
640
|
|
|
318
641
|
if (!verification.verified) {
|
|
@@ -333,70 +656,206 @@ export class Service extends DatabaseService<Model> {
|
|
|
333
656
|
return user;
|
|
334
657
|
}
|
|
335
658
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
},
|
|
659
|
+
@CaptureSpan()
|
|
660
|
+
public async generatePasskeyAuthenticationOptions(): Promise<{
|
|
661
|
+
options: any;
|
|
662
|
+
challengeId: string;
|
|
663
|
+
}> {
|
|
664
|
+
/*
|
|
665
|
+
* No email or credential allow-list is needed: the authenticator offers
|
|
666
|
+
* the discoverable credentials registered for this relying party.
|
|
667
|
+
*/
|
|
668
|
+
const options: any = await generateAuthenticationOptions({
|
|
669
|
+
rpID: this.getRelyingParty().rpID,
|
|
670
|
+
allowCredentials: [],
|
|
671
|
+
userVerification: "required",
|
|
350
672
|
});
|
|
673
|
+
const challengeId: string = randomBytes(32).toString("base64url");
|
|
351
674
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
675
|
+
await this.storeChallenge(
|
|
676
|
+
`${PASSKEY_CHALLENGE_PREFIX}${challengeId}`,
|
|
677
|
+
options.challenge,
|
|
678
|
+
);
|
|
355
679
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
680
|
+
return { options, challengeId };
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
@CaptureSpan()
|
|
684
|
+
public async verifyPasskeyAuthentication(data: {
|
|
685
|
+
challengeId: string;
|
|
686
|
+
credential: any;
|
|
687
|
+
}): Promise<User> {
|
|
688
|
+
if (
|
|
689
|
+
typeof data.challengeId !== "string" ||
|
|
690
|
+
!data.challengeId.match(/^[A-Za-z0-9_-]{43}$/)
|
|
691
|
+
) {
|
|
692
|
+
throw new BadDataException("Invalid passkey challenge");
|
|
360
693
|
}
|
|
361
694
|
|
|
362
|
-
|
|
695
|
+
/*
|
|
696
|
+
* Consume before validation. Failed assertions cannot reuse a challenge,
|
|
697
|
+
* and concurrent requests can never both claim the same ceremony.
|
|
698
|
+
*/
|
|
699
|
+
const challenge: string = await this.consumeChallenge(
|
|
700
|
+
`${PASSKEY_CHALLENGE_PREFIX}${data.challengeId}`,
|
|
701
|
+
);
|
|
702
|
+
|
|
363
703
|
if (
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
704
|
+
typeof data.credential?.id !== "string" ||
|
|
705
|
+
!data.credential.id ||
|
|
706
|
+
data.credential.type !== "public-key" ||
|
|
707
|
+
data.credential.rawId !== data.credential.id ||
|
|
708
|
+
typeof data.credential?.response?.userHandle !== "string" ||
|
|
709
|
+
!data.credential.response.userHandle ||
|
|
710
|
+
!["clientDataJSON", "authenticatorData", "signature"].every(
|
|
711
|
+
(field: string) => {
|
|
712
|
+
return (
|
|
713
|
+
typeof data.credential.response[field] === "string" &&
|
|
714
|
+
data.credential.response[field].length > 0
|
|
715
|
+
);
|
|
716
|
+
},
|
|
367
717
|
)
|
|
368
718
|
) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
id: userId,
|
|
372
|
-
data: {
|
|
373
|
-
webauthnChallenge: null as any,
|
|
374
|
-
webauthnChallengeExpiresAt: null as any,
|
|
375
|
-
},
|
|
376
|
-
props: {
|
|
377
|
-
isRoot: true,
|
|
378
|
-
},
|
|
379
|
-
});
|
|
719
|
+
throw new BadDataException("Invalid passkey credential");
|
|
720
|
+
}
|
|
380
721
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
722
|
+
const dbCredential: Model | null = await this.findOneBy({
|
|
723
|
+
query: {
|
|
724
|
+
credentialId: data.credential.id,
|
|
725
|
+
isVerified: true,
|
|
726
|
+
},
|
|
727
|
+
select: {
|
|
728
|
+
_id: true,
|
|
729
|
+
userId: true,
|
|
730
|
+
credentialId: true,
|
|
731
|
+
publicKey: true,
|
|
732
|
+
counter: true,
|
|
733
|
+
},
|
|
734
|
+
props: { isRoot: true },
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
if (
|
|
738
|
+
!dbCredential?.userId ||
|
|
739
|
+
!dbCredential.id ||
|
|
740
|
+
!dbCredential.publicKey ||
|
|
741
|
+
!dbCredential.credentialId ||
|
|
742
|
+
data.credential.response.userHandle !==
|
|
743
|
+
Buffer.from(dbCredential.userId.toString()).toString("base64url")
|
|
744
|
+
) {
|
|
745
|
+
throw new BadDataException("Passkey authentication failed");
|
|
384
746
|
}
|
|
385
747
|
|
|
386
|
-
const
|
|
748
|
+
const counter: number = Number(dbCredential.counter);
|
|
387
749
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
750
|
+
if (
|
|
751
|
+
!dbCredential.counter ||
|
|
752
|
+
!dbCredential.counter.match(/^\d+$/) ||
|
|
753
|
+
!Number.isSafeInteger(counter) ||
|
|
754
|
+
counter < 0
|
|
755
|
+
) {
|
|
756
|
+
throw new BadDataException("Invalid passkey counter");
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
const verification: any = await verifyAuthenticationResponse({
|
|
760
|
+
response: data.credential,
|
|
761
|
+
expectedChallenge: challenge,
|
|
762
|
+
expectedOrigin: this.getRelyingParty().origin,
|
|
763
|
+
expectedRPID: this.getRelyingParty().rpID,
|
|
764
|
+
requireUserVerification: true,
|
|
765
|
+
credential: {
|
|
766
|
+
id: dbCredential.credentialId,
|
|
767
|
+
publicKey: new Uint8Array(
|
|
768
|
+
Buffer.from(dbCredential.publicKey, "base64"),
|
|
769
|
+
),
|
|
770
|
+
counter,
|
|
394
771
|
},
|
|
395
|
-
|
|
396
|
-
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
if (
|
|
775
|
+
!verification.verified ||
|
|
776
|
+
!verification.authenticationInfo?.userVerified
|
|
777
|
+
) {
|
|
778
|
+
throw new BadDataException("Passkey authentication failed");
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
const updated: number = await this.updateOneById({
|
|
782
|
+
id: dbCredential.id,
|
|
783
|
+
data: {
|
|
784
|
+
counter: verification.authenticationInfo.newCounter.toString(),
|
|
397
785
|
},
|
|
786
|
+
props: { isRoot: true },
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
if (updated !== 1) {
|
|
790
|
+
throw new BadDataException("Passkey authentication failed");
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
const user: User | null = await UserService.findOneById({
|
|
794
|
+
id: dbCredential.userId,
|
|
795
|
+
select: { _id: true, email: true },
|
|
796
|
+
props: { isRoot: true },
|
|
398
797
|
});
|
|
399
798
|
|
|
799
|
+
if (!user) {
|
|
800
|
+
throw new BadDataException("Passkey authentication failed");
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
return user;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
private getRelyingParty(): { rpID: string; origin: string } {
|
|
807
|
+
const origin: URL = new URL(`${HttpProtocol}${Host.toString()}`);
|
|
808
|
+
|
|
809
|
+
/*
|
|
810
|
+
* Relying party IDs exclude the port; origins include it for installations
|
|
811
|
+
* hosted on a non-default port.
|
|
812
|
+
*/
|
|
813
|
+
return { rpID: webAuthnRelyingPartyId(), origin: origin.origin };
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
private getChallengeStore(): ClientType {
|
|
817
|
+
const client: ClientType | null = Redis.getClient();
|
|
818
|
+
|
|
819
|
+
if (!client || !Redis.isConnected()) {
|
|
820
|
+
throw new DatabaseNotConnectedException(
|
|
821
|
+
"Passkey challenge store is unavailable",
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
return client;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
private async storeChallenge(key: string, value: string): Promise<void> {
|
|
829
|
+
const result: string | null = await this.getChallengeStore().set(
|
|
830
|
+
key,
|
|
831
|
+
value,
|
|
832
|
+
"EX",
|
|
833
|
+
WEBAUTHN_CHALLENGE_TTL_MINUTES * 60,
|
|
834
|
+
);
|
|
835
|
+
|
|
836
|
+
if (result !== "OK") {
|
|
837
|
+
throw new BadDataException("Unable to create a WebAuthn challenge");
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
private async consumeChallenge(key: string): Promise<string> {
|
|
842
|
+
/*
|
|
843
|
+
* A Lua GET+DEL works on Redis versions before GETDEL was introduced.
|
|
844
|
+
* Both operations execute atomically and the key remains subject to TTL.
|
|
845
|
+
*/
|
|
846
|
+
const challenge: unknown = await this.getChallengeStore().eval(
|
|
847
|
+
"local value = redis.call('GET', KEYS[1]); " +
|
|
848
|
+
"if value then redis.call('DEL', KEYS[1]); end; return value",
|
|
849
|
+
1,
|
|
850
|
+
key,
|
|
851
|
+
);
|
|
852
|
+
|
|
853
|
+
if (typeof challenge !== "string" || !challenge) {
|
|
854
|
+
throw new BadDataException(
|
|
855
|
+
"WebAuthn challenge expired or was already used. Please try again.",
|
|
856
|
+
);
|
|
857
|
+
}
|
|
858
|
+
|
|
400
859
|
return challenge;
|
|
401
860
|
}
|
|
402
861
|
|