@oneuptime/common 13.0.0 → 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/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/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/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 +12 -0
- 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/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/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 +91 -29
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +132 -1
- package/Server/Services/NetworkDeviceAutoImportRuleService.ts +176 -2
- 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/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/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 +143 -0
- package/Server/Utils/DataSource/EgressGuard.ts +160 -15
- package/Server/Utils/Database/TruncateColumnValue.ts +1 -1
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +2 -0
- package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +33 -0
- package/Server/Utils/EmailRollup/EmailRollupWriter.ts +44 -0
- package/Server/Utils/LogRedaction.ts +2 -1
- package/Server/Utils/Monitor/MonitorAlert.ts +1 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +302 -3
- 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/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 +5 -0
- package/Server/Utils/Telemetry/ResourceHeartbeat.ts +2 -1
- package/Server/Utils/Telemetry/TelemetryEntity.ts +181 -1
- 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/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/DashboardLazyPages.test.tsx +458 -0
- package/Tests/App/Dashboard/DashboardToolbarPopupLayering.test.tsx +566 -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/GoogleSecOpsConnectionsErrors.test.tsx +244 -0
- package/Tests/App/Dashboard/GoogleSecOpsDiagnostics.test.tsx +724 -0
- package/Tests/App/Dashboard/MonitorTemplateSyncFields.test.tsx +539 -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/TwoFactorStatus.test.tsx +260 -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/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/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 +29 -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/Infrastructure/Postgres/UserNotificationEmailRollupMetadataMigration.test.ts +85 -0
- package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +34 -3
- package/Tests/Server/Middleware/PasskeyRateLimit.test.ts +141 -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/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/InventoryItemPromotionGate.test.ts +5 -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/MonitorTemplateServiceFieldSync.test.ts +994 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +22 -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/Permissions/ProjectCustomerSupportAccessColumn.test.ts +261 -0
- package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +95 -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/Dashboard/PublicDashboardResourceListPolicy.test.ts +345 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +896 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupMetadataIntegration.test.ts +246 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +299 -1
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +6 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +185 -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/TelemetryStepMetricAlias.test.ts +10 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +66 -1
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +362 -0
- 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/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/TelemetryEntity.test.ts +580 -0
- package/Tests/Server/Utils/Telemetry/VMwareSnapshotScan.test.ts +1748 -0
- package/Tests/Types/Cloud/CloudPlatform.test.ts +574 -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/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/UI/ColorPickerBuild.test.ts +86 -0
- package/Tests/UI/Components/Breadcrumbs.test.tsx +32 -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 +11 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +148 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +29 -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/DashboardVMwareListComponents.test.ts +548 -0
- package/Tests/Utils/Dashboard/DashboardResourceListSharedArgs.test.ts +17 -3
- package/Tests/Utils/LabelRuleImportExport.test.ts +583 -0
- package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
- package/Tests/Utils/Monitor/MonitorTemplateSyncUtil.test.ts +590 -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/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 +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/Docs/DocsLanguage.ts +1 -0
- package/Types/Exception/EgressGuardException.ts +65 -0
- package/Types/Icon/IconProp.ts +1 -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/VMwareAlertTemplates.ts +1070 -0
- package/Types/Monitor/VMwareMetricCatalog.ts +914 -0
- 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/StatusPage/StatusPageLanguage.ts +1 -0
- package/Types/Telemetry/EntityType.ts +21 -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/Calendar/Calendar.css +78 -0
- package/UI/Components/Calendar/Calendar.tsx +28 -3
- 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 +4 -0
- package/Utils/API.ts +34 -0
- 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/LabelRuleImportExport.ts +496 -0
- package/Utils/Monitor/MonitorTemplateSyncUtil.ts +164 -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/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/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/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 +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.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/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/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 +64 -26
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +124 -1
- 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/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/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/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 +113 -0
- 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 +2 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +18 -0
- 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/MonitorAlert.js +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +219 -4
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.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/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 +5 -0
- 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 +136 -1
- 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/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 +1 -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/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/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/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/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/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/Calendar/Calendar.js +24 -4
- package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
- 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/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/LabelRuleImportExport.js +356 -0
- package/build/dist/Utils/LabelRuleImportExport.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/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/package.json +1 -1
|
@@ -0,0 +1,649 @@
|
|
|
1
|
+
import "../TestingUtils/WebAuthnServiceMocks";
|
|
2
|
+
import UserWebAuthnService from "../../../Server/Services/UserWebAuthnService";
|
|
3
|
+
import UserService from "../../../Server/Services/UserService";
|
|
4
|
+
import User from "../../../Models/DatabaseModels/User";
|
|
5
|
+
import UserWebAuthn from "../../../Models/DatabaseModels/UserWebAuthn";
|
|
6
|
+
import Email from "../../../Types/Email";
|
|
7
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
8
|
+
import Redis from "../../../Server/Infrastructure/Redis";
|
|
9
|
+
import { getJestSpyOn } from "../../Spy";
|
|
10
|
+
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
11
|
+
import Exception from "../../../Types/Exception/Exception";
|
|
12
|
+
import {
|
|
13
|
+
generateAuthenticationOptions,
|
|
14
|
+
generateRegistrationOptions,
|
|
15
|
+
verifyAuthenticationResponse,
|
|
16
|
+
verifyRegistrationResponse,
|
|
17
|
+
} from "@simplewebauthn/server";
|
|
18
|
+
import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* ---------------------------------------------------------------------------
|
|
22
|
+
* The user verification POLICY, held down at the seam where it was broken.
|
|
23
|
+
*
|
|
24
|
+
* Issue #3652: a passkey could not be registered from a MacBook running folded
|
|
25
|
+
* shut, because the policy lives in two places and they had drifted apart.
|
|
26
|
+
* `generateRegistrationOptions` told the authenticator that verifying the user
|
|
27
|
+
* was "preferred" -- go ahead without it if you cannot -- and then
|
|
28
|
+
* `verifyRegistrationResponse`, left on its own default of
|
|
29
|
+
* `requireUserVerification: true`, refused the response that invitation
|
|
30
|
+
* produced. The same default sits on `verifyAuthenticationResponse`, so the
|
|
31
|
+
* same account could not sign in from the same laptop either.
|
|
32
|
+
*
|
|
33
|
+
* WHAT THIS FILE IS FOR, AND WHAT IT DELIBERATELY IS NOT
|
|
34
|
+
*
|
|
35
|
+
* Common's jest config maps `@simplewebauthn/server` to a stub
|
|
36
|
+
* (Common/Tests/__mocks__/simplewebauthn.js). A stub has no library default,
|
|
37
|
+
* so nothing here can demonstrate the FAILURE -- a test of that written
|
|
38
|
+
* against the stub would have passed before the fix and after it, which is
|
|
39
|
+
* worse than no test. The demonstration lives in
|
|
40
|
+
* App/Tests/FeatureSet/Identity/WebAuthnUserVerification.test.ts, where the
|
|
41
|
+
* real v13 library verifies real ES256 assertions from an authenticator that
|
|
42
|
+
* leaves the UV bit clear.
|
|
43
|
+
*
|
|
44
|
+
* What belongs HERE is the invariant that made the failure possible in the
|
|
45
|
+
* first place, and which is invisible end-to-end: that the ASK and the CHECK
|
|
46
|
+
* are the same policy. Both are arguments this service passes to the library,
|
|
47
|
+
* so both can be read straight off the call, and the agreement between them
|
|
48
|
+
* asserted directly. That is the property a future edit will break -- someone
|
|
49
|
+
* tightening one call site without the other -- and it breaks here loudly,
|
|
50
|
+
* without waiting on the four-minute end-to-end suite.
|
|
51
|
+
*
|
|
52
|
+
* These assertions are written against `requireUserVerification` being
|
|
53
|
+
* PRESENT, not merely falsy. Omitting the argument is what the bug WAS, and
|
|
54
|
+
* `undefined` is indistinguishable from `false` under `toBeFalsy()`.
|
|
55
|
+
* ---------------------------------------------------------------------------
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
const USER_ID: ObjectID = new ObjectID("7c1f2e3d-4a5b-4c6d-8e7f-081920304050");
|
|
59
|
+
const USER_EMAIL: Email = new Email("policy.user@example.com");
|
|
60
|
+
|
|
61
|
+
const CREDENTIAL_ID: string = "an-already-registered-credential";
|
|
62
|
+
|
|
63
|
+
type AsMockFunction = (fn: unknown) => jest.Mock;
|
|
64
|
+
|
|
65
|
+
const asMock: AsMockFunction = (fn: unknown): jest.Mock => {
|
|
66
|
+
return fn as unknown as jest.Mock;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
type FirstArgumentFunction = (fn: unknown) => Record<string, unknown>;
|
|
70
|
+
|
|
71
|
+
const firstArgument: FirstArgumentFunction = (
|
|
72
|
+
fn: unknown,
|
|
73
|
+
): Record<string, unknown> => {
|
|
74
|
+
const call: Array<unknown> | undefined = asMock(fn).mock.calls[0];
|
|
75
|
+
|
|
76
|
+
if (!call) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
"Expected the service to have called this library function",
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return call[0] as Record<string, unknown>;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
type BuildUserFunction = () => User;
|
|
86
|
+
|
|
87
|
+
const buildUser: BuildUserFunction = (): User => {
|
|
88
|
+
const user: User = new User();
|
|
89
|
+
user.id = USER_ID;
|
|
90
|
+
user.email = USER_EMAIL;
|
|
91
|
+
|
|
92
|
+
return user;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
type BuildCredentialRowFunction = () => UserWebAuthn;
|
|
96
|
+
|
|
97
|
+
const buildCredentialRow: BuildCredentialRowFunction = (): UserWebAuthn => {
|
|
98
|
+
const row: UserWebAuthn = new UserWebAuthn();
|
|
99
|
+
row.id = new ObjectID("0a0b0c0d-1e1f-4a2b-8c3d-4e5f60718293");
|
|
100
|
+
row.credentialId = CREDENTIAL_ID;
|
|
101
|
+
row.publicKey = Buffer.from("a public key").toString("base64");
|
|
102
|
+
row.counter = "0";
|
|
103
|
+
row.isVerified = true;
|
|
104
|
+
row.userId = USER_ID;
|
|
105
|
+
|
|
106
|
+
return row;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/* A credential body shaped the way navigator.credentials returns one. */
|
|
110
|
+
const CREDENTIAL_FROM_THE_BROWSER: Record<string, unknown> = {
|
|
111
|
+
id: CREDENTIAL_ID,
|
|
112
|
+
rawId: CREDENTIAL_ID,
|
|
113
|
+
type: "public-key",
|
|
114
|
+
response: {
|
|
115
|
+
clientDataJSON: "client-data",
|
|
116
|
+
attestationObject: "attestation",
|
|
117
|
+
authenticatorData: "authenticator-data",
|
|
118
|
+
signature: "signature",
|
|
119
|
+
},
|
|
120
|
+
clientExtensionResults: {},
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
let challengeCache: Map<string, string>;
|
|
124
|
+
let redisSet: jest.Mock;
|
|
125
|
+
let redisConsume: jest.Mock;
|
|
126
|
+
const REGISTRATION_KEY: string = `webauthn-registration-${USER_ID.toString()}`;
|
|
127
|
+
const AUTHENTICATION_KEY: string = `webauthn-security-key-login-${USER_ID.toString()}`;
|
|
128
|
+
|
|
129
|
+
beforeEach(() => {
|
|
130
|
+
jest.clearAllMocks();
|
|
131
|
+
challengeCache = new Map([
|
|
132
|
+
[
|
|
133
|
+
REGISTRATION_KEY,
|
|
134
|
+
JSON.stringify({
|
|
135
|
+
challenge: "mock-challenge",
|
|
136
|
+
requireUserVerification: false,
|
|
137
|
+
}),
|
|
138
|
+
],
|
|
139
|
+
[AUTHENTICATION_KEY, "mock-challenge"],
|
|
140
|
+
]);
|
|
141
|
+
redisSet = jest.fn(async (key: string, value: string): Promise<string> => {
|
|
142
|
+
challengeCache.set(key, value);
|
|
143
|
+
return "OK";
|
|
144
|
+
});
|
|
145
|
+
redisConsume = jest.fn(
|
|
146
|
+
async (
|
|
147
|
+
_script: string,
|
|
148
|
+
_keyCount: number,
|
|
149
|
+
key: string,
|
|
150
|
+
): Promise<string | null> => {
|
|
151
|
+
const value: string | null = challengeCache.get(key) || null;
|
|
152
|
+
challengeCache.delete(key);
|
|
153
|
+
return value;
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
getJestSpyOn(Redis, "getClient").mockReturnValue({
|
|
157
|
+
set: redisSet,
|
|
158
|
+
eval: redisConsume,
|
|
159
|
+
});
|
|
160
|
+
getJestSpyOn(Redis, "isConnected").mockReturnValue(true);
|
|
161
|
+
asMock(verifyRegistrationResponse).mockResolvedValue({
|
|
162
|
+
verified: true,
|
|
163
|
+
registrationInfo: {
|
|
164
|
+
credential: {
|
|
165
|
+
id: CREDENTIAL_ID,
|
|
166
|
+
publicKey: new Uint8Array([1, 2, 3]),
|
|
167
|
+
counter: 0,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
asMock(verifyAuthenticationResponse).mockResolvedValue({
|
|
172
|
+
verified: true,
|
|
173
|
+
authenticationInfo: { newCounter: 1 },
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
UserService.findOneById = jest.fn().mockResolvedValue(buildUser()) as never;
|
|
177
|
+
UserService.findOneBy = jest.fn().mockResolvedValue(buildUser()) as never;
|
|
178
|
+
UserService.updateOneById = jest.fn().mockResolvedValue(undefined) as never;
|
|
179
|
+
|
|
180
|
+
UserWebAuthnService.findBy = jest
|
|
181
|
+
.fn()
|
|
182
|
+
.mockResolvedValue([buildCredentialRow()]) as never;
|
|
183
|
+
UserWebAuthnService.findOneBy = jest
|
|
184
|
+
.fn()
|
|
185
|
+
.mockResolvedValue(buildCredentialRow()) as never;
|
|
186
|
+
UserWebAuthnService.create = jest.fn().mockResolvedValue({}) as never;
|
|
187
|
+
UserWebAuthnService.updateOneById = jest
|
|
188
|
+
.fn()
|
|
189
|
+
.mockResolvedValue(undefined) as never;
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
afterEach(() => {
|
|
193
|
+
jest.restoreAllMocks();
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
describe("UserWebAuthnService user verification policy", () => {
|
|
197
|
+
describe("registration", () => {
|
|
198
|
+
test("asks the authenticator for preferred user verification", async () => {
|
|
199
|
+
await UserWebAuthnService.generateRegistrationOptions({
|
|
200
|
+
userId: USER_ID,
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const options: Record<string, unknown> = firstArgument(
|
|
204
|
+
generateRegistrationOptions,
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
const authenticatorSelection: Record<string, unknown> = options[
|
|
208
|
+
"authenticatorSelection"
|
|
209
|
+
] as Record<string, unknown>;
|
|
210
|
+
|
|
211
|
+
expect(authenticatorSelection["userVerification"]).toBe("preferred");
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test("tells the verifier explicitly not to require it", async () => {
|
|
215
|
+
/*
|
|
216
|
+
* The single line the bug was missing. Asserted on its PRESENCE as well
|
|
217
|
+
* as its value: leaving the property off is precisely what went wrong,
|
|
218
|
+
* and the library then supplies `true` on our behalf.
|
|
219
|
+
*/
|
|
220
|
+
await UserWebAuthnService.verifyRegistration({
|
|
221
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
222
|
+
name: "MacBook Touch ID",
|
|
223
|
+
props: { userId: USER_ID },
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const verification: Record<string, unknown> = firstArgument(
|
|
227
|
+
verifyRegistrationResponse,
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
expect(verification).toHaveProperty("requireUserVerification");
|
|
231
|
+
expect(verification["requireUserVerification"]).toBe(false);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
describe("authentication", () => {
|
|
236
|
+
test("asks the authenticator for preferred user verification", async () => {
|
|
237
|
+
await UserWebAuthnService.generateAuthenticationOptions({
|
|
238
|
+
email: USER_EMAIL.toString(),
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const options: Record<string, unknown> = firstArgument(
|
|
242
|
+
generateAuthenticationOptions,
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
expect(options["userVerification"]).toBe("preferred");
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
test("tells the verifier explicitly not to require it", async () => {
|
|
249
|
+
/*
|
|
250
|
+
* The half of the bug that was never reported, because registration
|
|
251
|
+
* failed first. It is the more dangerous half: the password has already
|
|
252
|
+
* been accepted by the time an assertion is checked, so a refusal here
|
|
253
|
+
* is a locked account rather than a failed setup.
|
|
254
|
+
*/
|
|
255
|
+
await UserWebAuthnService.verifyAuthentication({
|
|
256
|
+
userId: USER_ID.toString(),
|
|
257
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
const verification: Record<string, unknown> = firstArgument(
|
|
261
|
+
verifyAuthenticationResponse,
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
expect(verification).toHaveProperty("requireUserVerification");
|
|
265
|
+
expect(verification["requireUserVerification"]).toBe(false);
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
describe("the ask and the check describe the same policy", () => {
|
|
270
|
+
/*
|
|
271
|
+
* THE INVARIANT, and the reason this file exists alongside the end-to-end
|
|
272
|
+
* test. Neither half is wrong on its own -- "preferred" is a legitimate
|
|
273
|
+
* ask and `requireUserVerification: true` is a legitimate check. The
|
|
274
|
+
* defect was the PAIR disagreeing, which no assertion on either half alone
|
|
275
|
+
* can catch.
|
|
276
|
+
*
|
|
277
|
+
* Stated as an equivalence rather than as two literals so that tightening
|
|
278
|
+
* the product's policy to "required" one day stays green here as long as
|
|
279
|
+
* BOTH sides move, and goes red the moment only one does.
|
|
280
|
+
*/
|
|
281
|
+
|
|
282
|
+
type PolicyPair = {
|
|
283
|
+
requested: unknown;
|
|
284
|
+
required: unknown;
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
type AssertAgreementFunction = (pair: PolicyPair) => void;
|
|
288
|
+
|
|
289
|
+
const assertAgreement: AssertAgreementFunction = (
|
|
290
|
+
pair: PolicyPair,
|
|
291
|
+
): void => {
|
|
292
|
+
expect(pair.requested).toEqual(expect.any(String));
|
|
293
|
+
expect(typeof pair.required).toBe("boolean");
|
|
294
|
+
expect(pair.required).toBe(pair.requested === "required");
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
test("on the registration flow", async () => {
|
|
298
|
+
await UserWebAuthnService.generateRegistrationOptions({
|
|
299
|
+
userId: USER_ID,
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
await UserWebAuthnService.verifyRegistration({
|
|
303
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
304
|
+
name: "MacBook Touch ID",
|
|
305
|
+
props: { userId: USER_ID },
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
const requested: Record<string, unknown> = firstArgument(
|
|
309
|
+
generateRegistrationOptions,
|
|
310
|
+
)["authenticatorSelection"] as Record<string, unknown>;
|
|
311
|
+
|
|
312
|
+
assertAgreement({
|
|
313
|
+
requested: requested["userVerification"],
|
|
314
|
+
required: firstArgument(verifyRegistrationResponse)[
|
|
315
|
+
"requireUserVerification"
|
|
316
|
+
],
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
test("on the authentication flow", async () => {
|
|
321
|
+
await UserWebAuthnService.generateAuthenticationOptions({
|
|
322
|
+
email: USER_EMAIL.toString(),
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
await UserWebAuthnService.verifyAuthentication({
|
|
326
|
+
userId: USER_ID.toString(),
|
|
327
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
assertAgreement({
|
|
331
|
+
requested: firstArgument(generateAuthenticationOptions)[
|
|
332
|
+
"userVerification"
|
|
333
|
+
],
|
|
334
|
+
required: firstArgument(verifyAuthenticationResponse)[
|
|
335
|
+
"requireUserVerification"
|
|
336
|
+
],
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
test("and the two flows agree with each other", async () => {
|
|
341
|
+
/*
|
|
342
|
+
* Registration and authentication are separate call sites with separate
|
|
343
|
+
* arguments, and a key is enrolled by one and used by the other. A
|
|
344
|
+
* product that asked for "preferred" at enrolment and "required" at
|
|
345
|
+
* sign-in would let a user set up an authenticator they could then never
|
|
346
|
+
* sign in with -- the worst version of this bug, because it only
|
|
347
|
+
* surfaces later, on a different machine, after the password has been
|
|
348
|
+
* accepted.
|
|
349
|
+
*/
|
|
350
|
+
await UserWebAuthnService.generateRegistrationOptions({
|
|
351
|
+
userId: USER_ID,
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
await UserWebAuthnService.generateAuthenticationOptions({
|
|
355
|
+
email: USER_EMAIL.toString(),
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
const registrationSelection: Record<string, unknown> = firstArgument(
|
|
359
|
+
generateRegistrationOptions,
|
|
360
|
+
)["authenticatorSelection"] as Record<string, unknown>;
|
|
361
|
+
|
|
362
|
+
expect(registrationSelection["userVerification"]).toBe(
|
|
363
|
+
firstArgument(generateAuthenticationOptions)["userVerification"],
|
|
364
|
+
);
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
describe("how a refusal from the library reaches the caller", () => {
|
|
369
|
+
/*
|
|
370
|
+
* The second half of the bug report -- "Get a 'Server Error' message" --
|
|
371
|
+
* and the reason the first half went undiagnosed. @simplewebauthn signals
|
|
372
|
+
* every refusal with a plain `Error`, and the last-resort handler in
|
|
373
|
+
* Common/Server/Utils/StartServer.ts has no branch for one: it answers
|
|
374
|
+
* `res.status(500).send({ error: "Server Error" })` and drops the message.
|
|
375
|
+
*
|
|
376
|
+
* Fast to assert here because the stub can be made to reject on demand;
|
|
377
|
+
* the end-to-end version, with the real library producing its own real
|
|
378
|
+
* messages, lives in
|
|
379
|
+
* App/Tests/FeatureSet/Identity/WebAuthnUserVerification.test.ts.
|
|
380
|
+
*/
|
|
381
|
+
|
|
382
|
+
const LIBRARY_REFUSAL: Error = new Error(
|
|
383
|
+
'Unexpected registration response origin "https://evil.test", expected "https://oneuptime.example.com"',
|
|
384
|
+
);
|
|
385
|
+
|
|
386
|
+
test("a registration refusal becomes an Exception carrying the reason", async () => {
|
|
387
|
+
asMock(verifyRegistrationResponse).mockRejectedValueOnce(LIBRARY_REFUSAL);
|
|
388
|
+
|
|
389
|
+
let thrown: unknown = null;
|
|
390
|
+
|
|
391
|
+
try {
|
|
392
|
+
await UserWebAuthnService.verifyRegistration({
|
|
393
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
394
|
+
name: "MacBook Touch ID",
|
|
395
|
+
props: { userId: USER_ID },
|
|
396
|
+
});
|
|
397
|
+
} catch (error) {
|
|
398
|
+
thrown = error;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/*
|
|
402
|
+
* `instanceof Exception` is exactly what the handler branches on, so it
|
|
403
|
+
* is the property worth asserting -- not merely "it threw".
|
|
404
|
+
*/
|
|
405
|
+
expect(thrown).toBeInstanceOf(BadDataException);
|
|
406
|
+
expect((thrown as Exception).message).toBe(LIBRARY_REFUSAL.message);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
test("an authentication refusal does the same", async () => {
|
|
410
|
+
asMock(verifyAuthenticationResponse).mockRejectedValueOnce(
|
|
411
|
+
LIBRARY_REFUSAL,
|
|
412
|
+
);
|
|
413
|
+
|
|
414
|
+
let thrown: unknown = null;
|
|
415
|
+
|
|
416
|
+
try {
|
|
417
|
+
await UserWebAuthnService.verifyAuthentication({
|
|
418
|
+
userId: USER_ID.toString(),
|
|
419
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
420
|
+
});
|
|
421
|
+
} catch (error) {
|
|
422
|
+
thrown = error;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
expect(thrown).toBeInstanceOf(BadDataException);
|
|
426
|
+
expect((thrown as Exception).message).toBe(LIBRARY_REFUSAL.message);
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
test("a refusal with nothing to say still says something", async () => {
|
|
430
|
+
/*
|
|
431
|
+
* Defensive, and cheap: an Error with an empty message would otherwise
|
|
432
|
+
* produce an empty-bodied 400, which reads to the user as a page that
|
|
433
|
+
* simply did nothing.
|
|
434
|
+
*/
|
|
435
|
+
asMock(verifyRegistrationResponse).mockRejectedValueOnce(new Error(""));
|
|
436
|
+
|
|
437
|
+
await expect(
|
|
438
|
+
UserWebAuthnService.verifyRegistration({
|
|
439
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
440
|
+
name: "MacBook Touch ID",
|
|
441
|
+
props: { userId: USER_ID },
|
|
442
|
+
}),
|
|
443
|
+
).rejects.toThrow(/could not verify this security key/i);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
test("a response the library merely marks unverified is still refused", async () => {
|
|
447
|
+
/*
|
|
448
|
+
* The library has two ways of saying no -- throwing, and returning
|
|
449
|
+
* `verified: false` -- and the wrapper only touches the first. The
|
|
450
|
+
* second must keep reaching the caller as it always did, or a
|
|
451
|
+
* credential that failed verification would be saved.
|
|
452
|
+
*/
|
|
453
|
+
asMock(verifyRegistrationResponse).mockResolvedValueOnce({
|
|
454
|
+
verified: false,
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
await expect(
|
|
458
|
+
UserWebAuthnService.verifyRegistration({
|
|
459
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
460
|
+
name: "MacBook Touch ID",
|
|
461
|
+
props: { userId: USER_ID },
|
|
462
|
+
}),
|
|
463
|
+
).rejects.toThrow(/registration verification failed/i);
|
|
464
|
+
|
|
465
|
+
expect(UserWebAuthnService.create).not.toHaveBeenCalled();
|
|
466
|
+
});
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
describe("which challenge namespace each flow uses", () => {
|
|
470
|
+
test("registering writes only the registration challenge with a five minute expiry", async () => {
|
|
471
|
+
await UserWebAuthnService.generateRegistrationOptions({
|
|
472
|
+
userId: USER_ID,
|
|
473
|
+
});
|
|
474
|
+
expect(redisSet).toHaveBeenCalledWith(
|
|
475
|
+
REGISTRATION_KEY,
|
|
476
|
+
expect.any(String),
|
|
477
|
+
"EX",
|
|
478
|
+
300,
|
|
479
|
+
);
|
|
480
|
+
expect(redisSet).toHaveBeenCalledTimes(1);
|
|
481
|
+
expect(UserService.updateOneById).not.toHaveBeenCalled();
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
test("signing in writes only the security key authentication challenge", async () => {
|
|
485
|
+
await UserWebAuthnService.generateAuthenticationOptions({
|
|
486
|
+
email: USER_EMAIL.toString(),
|
|
487
|
+
});
|
|
488
|
+
expect(redisSet).toHaveBeenCalledWith(
|
|
489
|
+
AUTHENTICATION_KEY,
|
|
490
|
+
expect.any(String),
|
|
491
|
+
"EX",
|
|
492
|
+
300,
|
|
493
|
+
);
|
|
494
|
+
expect(redisSet).toHaveBeenCalledTimes(1);
|
|
495
|
+
expect(UserService.updateOneById).not.toHaveBeenCalled();
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
test("consuming registration leaves a pending security key login intact", async () => {
|
|
499
|
+
await UserWebAuthnService.verifyRegistration({
|
|
500
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
501
|
+
name: "MacBook Touch ID",
|
|
502
|
+
props: { userId: USER_ID },
|
|
503
|
+
});
|
|
504
|
+
expect(challengeCache.has(REGISTRATION_KEY)).toBe(false);
|
|
505
|
+
expect(challengeCache.get(AUTHENTICATION_KEY)).toBe("mock-challenge");
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
test("consuming a security key login leaves a pending registration intact", async () => {
|
|
509
|
+
await UserWebAuthnService.verifyAuthentication({
|
|
510
|
+
userId: USER_ID.toString(),
|
|
511
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
512
|
+
});
|
|
513
|
+
expect(challengeCache.has(AUTHENTICATION_KEY)).toBe(false);
|
|
514
|
+
expect(challengeCache.has(REGISTRATION_KEY)).toBe(true);
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
test("each flow consumes only its own challenge", async () => {
|
|
518
|
+
await UserWebAuthnService.verifyAuthentication({
|
|
519
|
+
userId: USER_ID.toString(),
|
|
520
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
521
|
+
});
|
|
522
|
+
expect(redisConsume).toHaveBeenCalledWith(
|
|
523
|
+
expect.any(String),
|
|
524
|
+
1,
|
|
525
|
+
AUTHENTICATION_KEY,
|
|
526
|
+
);
|
|
527
|
+
expect(redisConsume).toHaveBeenCalledTimes(1);
|
|
528
|
+
});
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
describe("what an anonymous caller learns about an account", () => {
|
|
532
|
+
/*
|
|
533
|
+
* generateAuthenticationOptions is reached by POSTing an email and nothing
|
|
534
|
+
* else, from anybody. Two distinguishable refusals made it an
|
|
535
|
+
* account-existence oracle plus a second one naming which accounts are
|
|
536
|
+
* protected by a security key -- on a surface whose other doors go out of
|
|
537
|
+
* their way not to say which half of a credential was wrong.
|
|
538
|
+
*/
|
|
539
|
+
|
|
540
|
+
type RefusalForFunction = (setUp: () => void) => Promise<Exception>;
|
|
541
|
+
|
|
542
|
+
const refusalFor: RefusalForFunction = async (
|
|
543
|
+
setUp: () => void,
|
|
544
|
+
): Promise<Exception> => {
|
|
545
|
+
setUp();
|
|
546
|
+
|
|
547
|
+
try {
|
|
548
|
+
await UserWebAuthnService.generateAuthenticationOptions({
|
|
549
|
+
email: USER_EMAIL.toString(),
|
|
550
|
+
});
|
|
551
|
+
} catch (error) {
|
|
552
|
+
return error as Exception;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
throw new Error("Expected this to reject, and it resolved");
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
test("an unknown address and a known one without a key get the same answer", async () => {
|
|
559
|
+
const unknownAccount: Exception = await refusalFor((): void => {
|
|
560
|
+
UserService.findOneBy = jest.fn().mockResolvedValue(null) as never;
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
const noSecurityKey: Exception = await refusalFor((): void => {
|
|
564
|
+
UserService.findOneBy = jest
|
|
565
|
+
.fn()
|
|
566
|
+
.mockResolvedValue(buildUser()) as never;
|
|
567
|
+
UserWebAuthnService.findBy = jest.fn().mockResolvedValue([]) as never;
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
expect(unknownAccount.message).toBe(noSecurityKey.message);
|
|
571
|
+
expect(unknownAccount).toBeInstanceOf(BadDataException);
|
|
572
|
+
expect(noSecurityKey).toBeInstanceOf(BadDataException);
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
test("neither answer describes what was actually missing", async () => {
|
|
576
|
+
const unknownAccount: Exception = await refusalFor((): void => {
|
|
577
|
+
UserService.findOneBy = jest.fn().mockResolvedValue(null) as never;
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
expect(unknownAccount.message).not.toMatch(/user not found/i);
|
|
581
|
+
expect(unknownAccount.message).not.toMatch(/no webauthn credentials/i);
|
|
582
|
+
expect(unknownAccount.message).not.toContain(USER_EMAIL.toString());
|
|
583
|
+
});
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
describe("what the policy does not touch", () => {
|
|
587
|
+
test("the challenge is still taken from the server, never from the caller", async () => {
|
|
588
|
+
/*
|
|
589
|
+
* Relaxing user verification removes one check, and this is the check it
|
|
590
|
+
* must not be confused with. The challenge is what makes a response
|
|
591
|
+
* fresh; it is read from Redis rather than from the request, and
|
|
592
|
+
* it is what the library is told to expect.
|
|
593
|
+
*/
|
|
594
|
+
await UserWebAuthnService.verifyRegistration({
|
|
595
|
+
credential: {
|
|
596
|
+
...CREDENTIAL_FROM_THE_BROWSER,
|
|
597
|
+
expectedChallenge: "a challenge the caller would like used",
|
|
598
|
+
},
|
|
599
|
+
name: "MacBook Touch ID",
|
|
600
|
+
props: { userId: USER_ID },
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
expect(
|
|
604
|
+
firstArgument(verifyRegistrationResponse)["expectedChallenge"],
|
|
605
|
+
).toBe("mock-challenge");
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
test("the origin and relying party are still pinned", async () => {
|
|
609
|
+
/*
|
|
610
|
+
* Phishing resistance, which has nothing to do with user verification
|
|
611
|
+
* and everything to do with these two arguments being present at all.
|
|
612
|
+
*/
|
|
613
|
+
await UserWebAuthnService.verifyAuthentication({
|
|
614
|
+
userId: USER_ID.toString(),
|
|
615
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
const verification: Record<string, unknown> = firstArgument(
|
|
619
|
+
verifyAuthenticationResponse,
|
|
620
|
+
);
|
|
621
|
+
|
|
622
|
+
expect(verification["expectedOrigin"]).toEqual(expect.any(String));
|
|
623
|
+
expect(verification["expectedRPID"]).toEqual(expect.any(String));
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
test("the challenge is still spent as it is read", async () => {
|
|
627
|
+
/*
|
|
628
|
+
* One-time use: the challenge is consumed during verification, so the same
|
|
629
|
+
* captured response cannot be replayed. Asserted here because it is the
|
|
630
|
+
* other write this code path makes to the User row, and a refactor of
|
|
631
|
+
* the policy constants sits close enough to it to disturb it.
|
|
632
|
+
*/
|
|
633
|
+
await UserWebAuthnService.verifyRegistration({
|
|
634
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
635
|
+
name: "MacBook Touch ID",
|
|
636
|
+
props: { userId: USER_ID },
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
expect(challengeCache.has(REGISTRATION_KEY)).toBe(false);
|
|
640
|
+
await expect(
|
|
641
|
+
UserWebAuthnService.verifyRegistration({
|
|
642
|
+
credential: CREDENTIAL_FROM_THE_BROWSER,
|
|
643
|
+
name: "MacBook Touch ID",
|
|
644
|
+
props: { userId: USER_ID },
|
|
645
|
+
}),
|
|
646
|
+
).rejects.toThrow("already used");
|
|
647
|
+
});
|
|
648
|
+
});
|
|
649
|
+
});
|