@oneuptime/common 12.0.2 → 12.0.4
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/CephCluster.ts +14 -0
- package/Models/DatabaseModels/CodeRepository.ts +14 -6
- package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +14 -0
- package/Models/DatabaseModels/DockerHost.ts +14 -0
- package/Models/DatabaseModels/GlobalOidcProject.ts +18 -0
- package/Models/DatabaseModels/GlobalSsoProject.ts +18 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/IoTFleet.ts +14 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +14 -0
- package/Models/DatabaseModels/LogDropFilter.ts +9 -20
- package/Models/DatabaseModels/NetworkDevice.ts +14 -0
- package/Models/DatabaseModels/NetworkInterface.ts +18 -0
- package/Models/DatabaseModels/Project.ts +16 -2
- package/Models/DatabaseModels/ProxmoxCluster.ts +14 -0
- package/Models/DatabaseModels/Service.ts +30 -0
- package/Models/DatabaseModels/StatusPageMonitorRule.ts +911 -0
- package/Models/DatabaseModels/StatusPagePrivateUser.ts +30 -0
- package/Models/DatabaseModels/StatusPageResource.ts +73 -0
- package/Models/DatabaseModels/TraceDropFilter.ts +9 -20
- package/Models/DatabaseModels/User.ts +30 -0
- package/Server/API/AIAgentDataAPI.ts +31 -0
- package/Server/API/BaseAPI.ts +13 -2
- package/Server/API/DashboardAPI.ts +458 -12
- package/Server/API/GitHubAPI.ts +119 -283
- package/Server/API/UserAPI.ts +263 -1
- package/Server/EnvironmentConfig.ts +38 -4
- package/Server/Infrastructure/GlobalCache.ts +152 -0
- package/Server/Infrastructure/Postgres/DataSourceOptions.ts +16 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.ts +123 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.ts +21 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.ts +68 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +100 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +214 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.ts +69 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
- package/Server/Services/AlertStateTimelineService.ts +20 -0
- package/Server/Services/AnalyticsDatabaseService.ts +72 -1
- package/Server/Services/CephClusterService.ts +26 -86
- package/Server/Services/CloudResourceService.ts +23 -83
- package/Server/Services/CodeRepositoryService.ts +105 -2
- package/Server/Services/DatabaseService.ts +296 -2
- package/Server/Services/DockerHostService.ts +19 -79
- package/Server/Services/DockerSwarmClusterService.ts +27 -88
- package/Server/Services/HostService.ts +46 -99
- package/Server/Services/IncidentStateTimelineService.ts +20 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/IoTFleetService.ts +19 -79
- package/Server/Services/KubernetesClusterService.ts +17 -78
- package/Server/Services/LabelService.ts +57 -10
- package/Server/Services/MetricTypeService.ts +84 -0
- package/Server/Services/MonitorService.ts +89 -14
- package/Server/Services/MonitorStatusTimelineService.ts +29 -0
- package/Server/Services/MonitorTemplateService.ts +65 -0
- package/Server/Services/OpenTelemetryIngestService.ts +230 -26
- package/Server/Services/PodmanHostService.ts +19 -79
- package/Server/Services/ProxmoxClusterService.ts +23 -83
- package/Server/Services/RumApplicationService.ts +19 -80
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +21 -0
- package/Server/Services/ServerlessFunctionService.ts +24 -85
- package/Server/Services/ServiceService.ts +299 -73
- package/Server/Services/StatusPageMonitorRuleEngineService.ts +752 -0
- package/Server/Services/StatusPageMonitorRuleService.ts +471 -0
- package/Server/Services/TelemetryEntityRelationshipService.ts +1 -0
- package/Server/Services/TelemetryEntityService.ts +1 -0
- package/Server/Services/UserService.ts +184 -0
- package/Server/Utils/AI/Toolbox/CodeTools.ts +45 -4
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +13 -0
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +157 -4
- package/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.ts +130 -0
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +170 -39
- package/Server/Utils/Monitor/MonitorResource.ts +63 -36
- package/Server/Utils/Monitor/MonitorStatusTimeline.ts +36 -0
- package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +148 -127
- package/Server/Utils/Monitor/MonitorStepsReferenceExtractor.ts +434 -0
- package/Server/Utils/PasswordHash.ts +306 -0
- package/Server/Utils/SingleFlight.ts +83 -0
- package/Server/Utils/StatusPage/MonitorRulePatternValidator.ts +46 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +107 -26
- package/Server/Utils/Telemetry/ResourceHeartbeat.ts +314 -0
- package/Server/Utils/Telemetry/Telemetry.ts +351 -122
- package/Tests/App/Dashboard/OverviewCustomFields.test.tsx +333 -0
- package/Tests/App/Dashboard/UserCustomFields.test.tsx +392 -0
- package/Tests/App/Dashboard/WidgetCatalog.test.ts +2 -0
- package/Tests/Models/DatabaseModels/ColumnTransformerInvariants.test.ts +306 -0
- package/Tests/Models/DatabaseModels/NumberColumnDeserialization.test.ts +333 -0
- package/Tests/Models/DatabaseModels/StatusPageMonitorRuleModel.test.ts +190 -0
- package/Tests/Server/API/AIAgentDataRepositoryToken.test.ts +381 -0
- package/Tests/Server/API/DashboardPublicAttributeValuesAPI.test.ts +943 -0
- package/Tests/Server/API/DashboardPublicMetricsAggregateAPI.test.ts +1296 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +26 -0
- package/Tests/Server/API/DashboardPublicTemplatePayloads.test.ts +598 -0
- package/Tests/Server/API/GitHubAppInstallationBindingAPI.test.ts +539 -0
- package/Tests/Server/API/Helpers.ts +6 -1
- package/Tests/Server/API/UserProjectsAPI.test.ts +852 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +354 -0
- package/Tests/Server/Infrastructure/PostgresLockTimeoutOptions.test.ts +181 -0
- package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +215 -0
- package/Tests/Server/Services/AddPerUserPasswordSaltMigration.test.ts +178 -0
- package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +582 -0
- package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +5 -0
- package/Tests/Server/Services/CodeRepositoryInstallationBinding.test.ts +305 -0
- package/Tests/Server/Services/CodeRepositoryResolutionBinding.test.ts +147 -0
- package/Tests/Server/Services/DatabaseServicePerUserPasswordSalt.test.ts +870 -0
- package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlocked.test.ts +342 -0
- package/Tests/Server/Services/DropFilterSaveValidation.test.ts +245 -0
- package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +163 -15
- package/Tests/Server/Services/MetricTypeAttachServices.test.ts +222 -0
- package/Tests/Server/Services/MissingReferenceWriteGuard.test.ts +614 -0
- package/Tests/Server/Services/MonitorStatusTimelineFastPath.test.ts +23 -0
- package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +568 -0
- package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +305 -56
- package/Tests/Server/Services/RestoreDroppedUniqueIndexesMigration.test.ts +386 -0
- package/Tests/Server/Services/RestoreServiceLowerNameIndexMigration.test.ts +240 -0
- package/Tests/Server/Services/ServiceUpdateLastSeenSplitGates.test.ts +705 -0
- package/Tests/Server/Services/StatusPageMonitorRuleEngineService.test.ts +1719 -0
- package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +1212 -0
- package/Tests/Server/Services/StatusPageMonitorRuleMonitorCreateHook.test.ts +228 -0
- package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +885 -0
- package/Tests/Server/Services/WidenHashedStringColumnsForScryptMigration.test.ts +220 -0
- package/Tests/Server/Utils/AI/CodeTools.test.ts +47 -1
- package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +10 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +267 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +120 -0
- package/Tests/Server/Utils/CodeRepository/GitHubInstallationBinding.test.ts +292 -0
- package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +260 -13
- package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +302 -0
- package/Tests/Server/Utils/GitHubInstallationOwnershipVerification.test.ts +340 -0
- package/Tests/Server/Utils/GitHubWebhookAndTreeCacheIsolation.test.ts +250 -0
- package/Tests/Server/Utils/MetricTypeIndexConvergence.test.ts +598 -0
- package/Tests/Server/Utils/Monitor/MonitorStatusTimelineUnusableStatus.test.ts +154 -0
- package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +638 -92
- package/Tests/Server/Utils/Monitor/MonitorStepsReferenceExtractor.test.ts +724 -0
- package/Tests/Server/Utils/PasswordHash.test.ts +555 -0
- package/Tests/Server/Utils/SingleFlight.test.ts +221 -0
- package/Tests/Types/Dashboard/NetworkDashboardTemplate.test.ts +793 -0
- package/Tests/Types/Database/BigIntColumnTransformer.test.ts +147 -0
- package/Tests/Types/Database/ColumnLength.test.ts +7 -1
- package/Tests/Types/Database/DatabasePropertyTransformer.test.ts +140 -0
- package/Tests/Types/Database/NumericColumnValue.test.ts +127 -0
- package/Tests/Types/Decimal.test.ts +37 -0
- package/Tests/Types/HashedStringPerUserSalt.test.ts +476 -0
- package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +293 -0
- package/Tests/Types/Monitor/HostAlertTemplates.test.ts +249 -0
- package/Tests/Types/Monitor/IotAlertTemplates.test.ts +320 -0
- package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +271 -0
- package/Tests/Types/Monitor/SnmpVersionParsing.test.ts +152 -0
- package/Tests/Types/Port.test.ts +38 -0
- package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +696 -0
- package/Tests/UI/Components/LogsHistogram.test.tsx +276 -0
- package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +489 -0
- package/Tests/UI/Components/UseLogsHistogram.test.tsx +500 -0
- package/Tests/UI/Utils/UserProjectsModelAPI.test.ts +714 -0
- package/Tests/Utils/Dashboard/Components/DashboardComponentsUtil.test.ts +120 -0
- package/Tests/Utils/Dashboard/DashboardNetworkMapComponent.test.ts +327 -0
- package/Tests/Utils/TeamMembersByProject.test.ts +655 -0
- package/Types/Dashboard/DashboardComponentType.ts +1 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.ts +40 -0
- package/Types/Dashboard/DashboardTemplates.ts +397 -0
- package/Types/Database/BigIntColumnTransformer.ts +74 -0
- package/Types/Database/ColumnLength.ts +9 -1
- package/Types/Database/DatabaseProperty.ts +26 -0
- package/Types/Database/NumericColumnValue.ts +128 -0
- package/Types/Database/TableColumn.ts +11 -0
- package/Types/Database/UnsynchronizedIndex.ts +48 -0
- package/Types/Decimal.ts +16 -4
- package/Types/HashedString.ts +139 -4
- package/Types/Permission.ts +48 -0
- package/Types/Port.ts +16 -4
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +85 -11
- package/UI/Components/LogsViewer/useLiveLogsRefresh.ts +86 -0
- package/UI/Components/LogsViewer/useLogsHistogram.ts +113 -0
- package/UI/Components/Navbar/NavBar.tsx +12 -2
- package/UI/Components/Navbar/NavBarMenuModal.tsx +19 -7
- package/UI/Utils/ModelAPI/UserProjectsModelAPI.ts +257 -0
- package/Utils/Dashboard/Components/DashboardNetworkMapComponent.ts +136 -0
- package/Utils/Dashboard/Components/Index.ts +7 -0
- package/Utils/TeamMembersByProject.ts +237 -0
- package/build/dist/Models/DatabaseModels/CephCluster.js +16 -1
- package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CodeRepository.js +14 -6
- package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +12 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +16 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +16 -1
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +16 -1
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IoTFleet.js +16 -1
- package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +16 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogDropFilter.js +9 -20
- package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +16 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkInterface.js +16 -1
- package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +16 -2
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +16 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Service.js +28 -1
- package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js +925 -0
- package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +32 -0
- package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageResource.js +72 -0
- package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js +9 -20
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +32 -0
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Server/API/AIAgentDataAPI.js +21 -2
- package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +11 -1
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +343 -10
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/GitHubAPI.js +94 -167
- package/build/dist/Server/API/GitHubAPI.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +187 -2
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +34 -4
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/GlobalCache.js +120 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +5 -3
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js +48 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js +59 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +93 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js +101 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js +66 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.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/Services/AlertStateTimelineService.js +19 -0
- package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +57 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterService.js +26 -76
- package/build/dist/Server/Services/CephClusterService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceService.js +23 -73
- package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
- package/build/dist/Server/Services/CodeRepositoryService.js +90 -2
- package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +246 -2
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostService.js +19 -69
- package/build/dist/Server/Services/DockerHostService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterService.js +27 -78
- package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
- package/build/dist/Server/Services/HostService.js +58 -102
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +19 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/IoTFleetService.js +19 -69
- package/build/dist/Server/Services/IoTFleetService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterService.js +17 -68
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/LabelService.js +42 -7
- package/build/dist/Server/Services/LabelService.js.map +1 -1
- package/build/dist/Server/Services/MetricTypeService.js +74 -0
- package/build/dist/Server/Services/MetricTypeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +81 -9
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +28 -0
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +60 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +155 -25
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostService.js +19 -69
- package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterService.js +23 -73
- package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
- package/build/dist/Server/Services/RumApplicationService.js +19 -70
- package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +20 -0
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionService.js +24 -75
- package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
- package/build/dist/Server/Services/ServiceService.js +236 -61
- package/build/dist/Server/Services/ServiceService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +603 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleService.js +401 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleService.js.map +1 -0
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +1 -0
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityService.js +1 -0
- package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +165 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js +31 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +13 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +126 -4
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js +136 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js.map +1 -0
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +105 -29
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +56 -32
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +30 -3
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +110 -98
- package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js +312 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js.map +1 -0
- package/build/dist/Server/Utils/PasswordHash.js +237 -0
- package/build/dist/Server/Utils/PasswordHash.js.map +1 -0
- package/build/dist/Server/Utils/SingleFlight.js +76 -0
- package/build/dist/Server/Utils/SingleFlight.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +29 -0
- package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +78 -19
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +160 -0
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +279 -104
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -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/DashboardNetworkMapComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js +368 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/Database/BigIntColumnTransformer.js +66 -0
- package/build/dist/Types/Database/BigIntColumnTransformer.js.map +1 -0
- package/build/dist/Types/Database/ColumnLength.js +9 -1
- package/build/dist/Types/Database/ColumnLength.js.map +1 -1
- package/build/dist/Types/Database/DatabaseProperty.js +25 -0
- package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
- package/build/dist/Types/Database/NumericColumnValue.js +97 -0
- package/build/dist/Types/Database/NumericColumnValue.js.map +1 -0
- package/build/dist/Types/Database/TableColumn.js.map +1 -1
- package/build/dist/Types/Database/UnsynchronizedIndex.js +46 -0
- package/build/dist/Types/Database/UnsynchronizedIndex.js.map +1 -0
- package/build/dist/Types/Decimal.js +14 -3
- package/build/dist/Types/Decimal.js.map +1 -1
- package/build/dist/Types/HashedString.js +95 -5
- package/build/dist/Types/HashedString.js.map +1 -1
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Port.js +15 -5
- package/build/dist/Types/Port.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +51 -10
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js +44 -0
- package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +75 -0
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -0
- package/build/dist/UI/Components/Navbar/NavBar.js +3 -1
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +19 -7
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js +156 -0
- package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js +114 -0
- package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/TeamMembersByProject.js +145 -0
- package/build/dist/Utils/TeamMembersByProject.js.map +1 -0
- package/package.json +1 -1
package/Server/API/GitHubAPI.ts
CHANGED
|
@@ -17,36 +17,39 @@ import {
|
|
|
17
17
|
HomeClientUrl,
|
|
18
18
|
} from "../EnvironmentConfig";
|
|
19
19
|
import ObjectID from "../../Types/ObjectID";
|
|
20
|
-
import GitHubUtil
|
|
21
|
-
GitHubRepository,
|
|
22
|
-
GitHubInstallationNotFoundError,
|
|
23
|
-
} from "../Utils/CodeRepository/GitHub/GitHub";
|
|
20
|
+
import GitHubUtil from "../Utils/CodeRepository/GitHub/GitHub";
|
|
24
21
|
import CodeRepositoryService, {
|
|
25
22
|
ImportReposFromInstallationResult,
|
|
26
23
|
} from "../Services/CodeRepositoryService";
|
|
27
24
|
import ProjectService from "../Services/ProjectService";
|
|
28
25
|
import AccessTokenService from "../Services/AccessTokenService";
|
|
29
|
-
import CodeRepository from "../../Models/DatabaseModels/CodeRepository";
|
|
30
26
|
import Project from "../../Models/DatabaseModels/Project";
|
|
31
|
-
import CodeRepositoryType from "../../Types/CodeRepository/CodeRepositoryType";
|
|
32
27
|
import URL from "../../Types/API/URL";
|
|
33
28
|
import UserMiddleware from "../Middleware/UserAuthorization";
|
|
34
29
|
import JSONWebToken from "../Utils/JsonWebToken";
|
|
35
|
-
import BaseModel from "../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
36
30
|
import { UserTenantAccessPermission } from "../../Types/Permission";
|
|
37
31
|
|
|
38
32
|
export default class GitHubAPI {
|
|
39
33
|
/*
|
|
40
|
-
* Resolves the projects linked to a GitHub App installation.
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
34
|
+
* Resolves the projects linked to a GitHub App installation.
|
|
35
|
+
*
|
|
36
|
+
* Project.gitHubAppInstallationId is the only source consulted, because it
|
|
37
|
+
* is the only one GitHub has vouched for — the install callback writes it
|
|
38
|
+
* after verifying the installer controls the installation, and the
|
|
39
|
+
* uninstall webhook clears it.
|
|
40
|
+
*
|
|
41
|
+
* This used to fall back to CodeRepository rows carrying the installation
|
|
42
|
+
* ID. That inverted the trust: a row is supposed to derive its right to an
|
|
43
|
+
* installation FROM its project, so letting a row nominate its project as a
|
|
44
|
+
* link target meant anyone who could write an installation ID onto a row in
|
|
45
|
+
* their own project would have that project treated as an owner of the
|
|
46
|
+
* installation — and every webhook would then import the victim's
|
|
47
|
+
* repositories into it.
|
|
45
48
|
*/
|
|
46
49
|
private static async getProjectIdsForInstallation(
|
|
47
50
|
installationId: string,
|
|
48
51
|
): Promise<Array<ObjectID>> {
|
|
49
|
-
const projectIds: Array<
|
|
52
|
+
const projectIds: Array<ObjectID> = [];
|
|
50
53
|
|
|
51
54
|
const projects: Array<Project> = await ProjectService.findBy({
|
|
52
55
|
query: {
|
|
@@ -64,37 +67,11 @@ export default class GitHubAPI {
|
|
|
64
67
|
|
|
65
68
|
for (const project of projects) {
|
|
66
69
|
if (project.id) {
|
|
67
|
-
projectIds.push(project.id
|
|
70
|
+
projectIds.push(project.id);
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
73
|
|
|
71
|
-
|
|
72
|
-
await CodeRepositoryService.findBy({
|
|
73
|
-
query: {
|
|
74
|
-
gitHubAppInstallationId: installationId,
|
|
75
|
-
},
|
|
76
|
-
select: {
|
|
77
|
-
projectId: true,
|
|
78
|
-
},
|
|
79
|
-
limit: LIMIT_MAX,
|
|
80
|
-
skip: 0,
|
|
81
|
-
props: {
|
|
82
|
-
isRoot: true,
|
|
83
|
-
},
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
for (const codeRepository of codeRepositories) {
|
|
87
|
-
if (
|
|
88
|
-
codeRepository.projectId &&
|
|
89
|
-
!projectIds.includes(codeRepository.projectId.toString())
|
|
90
|
-
) {
|
|
91
|
-
projectIds.push(codeRepository.projectId.toString());
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return projectIds.map((projectId: string) => {
|
|
96
|
-
return new ObjectID(projectId);
|
|
97
|
-
});
|
|
74
|
+
return projectIds;
|
|
98
75
|
}
|
|
99
76
|
|
|
100
77
|
// Imports all repositories in an installation into every project linked to it.
|
|
@@ -260,6 +237,62 @@ export default class GitHubAPI {
|
|
|
260
237
|
);
|
|
261
238
|
}
|
|
262
239
|
|
|
240
|
+
/*
|
|
241
|
+
* Prove the installation actually belongs to the person completing
|
|
242
|
+
* this redirect, before writing the binding everything downstream
|
|
243
|
+
* trusts.
|
|
244
|
+
*
|
|
245
|
+
* A valid `state` only says "this OneUptime user asked to install
|
|
246
|
+
* something for this project" — it says nothing about WHICH
|
|
247
|
+
* installation, and `installation_id` is an unauthenticated integer
|
|
248
|
+
* in a query string. Without this step anyone could start an install
|
|
249
|
+
* for their own project, then hand-edit the callback URL to a victim's
|
|
250
|
+
* installation ID: OneUptime would record their project as the owner
|
|
251
|
+
* of that installation, import the victim's private repositories into
|
|
252
|
+
* it, and mint write-scoped tokens for them on demand.
|
|
253
|
+
*
|
|
254
|
+
* The OAuth `code` is the missing proof. GitHub mints it for one
|
|
255
|
+
* GitHub account, it is single-use, and trading it in tells us which
|
|
256
|
+
* installations that account can actually administer.
|
|
257
|
+
*/
|
|
258
|
+
const oauthCode: string | undefined = req.query["code"]?.toString();
|
|
259
|
+
|
|
260
|
+
if (!oauthCode) {
|
|
261
|
+
return Response.sendErrorResponse(
|
|
262
|
+
req,
|
|
263
|
+
res,
|
|
264
|
+
new BadDataException(
|
|
265
|
+
'GitHub did not return an authorization code, so this installation could not be verified. Please enable "Request user authorization (OAuth) during installation" in the GitHub App settings and install again.',
|
|
266
|
+
),
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
try {
|
|
271
|
+
await GitHubUtil.assertUserControlsInstallation({
|
|
272
|
+
oauthCode: oauthCode,
|
|
273
|
+
installationId: installationId,
|
|
274
|
+
});
|
|
275
|
+
} catch (verificationError) {
|
|
276
|
+
logger.error(
|
|
277
|
+
`GitHub Auth Callback: refusing to bind installation ${installationId} to project ${projectId} — could not verify the installing user controls it.`,
|
|
278
|
+
getLogAttributesFromRequest(req as OneUptimeRequest),
|
|
279
|
+
);
|
|
280
|
+
logger.error(
|
|
281
|
+
verificationError,
|
|
282
|
+
getLogAttributesFromRequest(req as OneUptimeRequest),
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
return Response.sendErrorResponse(
|
|
286
|
+
req,
|
|
287
|
+
res,
|
|
288
|
+
verificationError instanceof Error
|
|
289
|
+
? new BadDataException(verificationError.message)
|
|
290
|
+
: new BadDataException(
|
|
291
|
+
"Could not verify this GitHub App installation.",
|
|
292
|
+
),
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
|
|
263
296
|
/*
|
|
264
297
|
* Store the installation ID in the project
|
|
265
298
|
* This allows reuse when connecting additional repositories
|
|
@@ -329,6 +362,7 @@ export default class GitHubAPI {
|
|
|
329
362
|
// Initiate GitHub App installation
|
|
330
363
|
router.get(
|
|
331
364
|
"/github/auth/install",
|
|
365
|
+
UserMiddleware.getUserMiddleware,
|
|
332
366
|
async (req: ExpressRequest, res: ExpressResponse) => {
|
|
333
367
|
try {
|
|
334
368
|
if (!GitHubAppName) {
|
|
@@ -341,75 +375,28 @@ export default class GitHubAPI {
|
|
|
341
375
|
);
|
|
342
376
|
}
|
|
343
377
|
|
|
344
|
-
const
|
|
345
|
-
req.query["projectId"]?.toString();
|
|
346
|
-
const userId: string | undefined = req.query["userId"]?.toString();
|
|
347
|
-
|
|
348
|
-
if (!projectId || !userId) {
|
|
349
|
-
return Response.sendErrorResponse(
|
|
350
|
-
req,
|
|
351
|
-
res,
|
|
352
|
-
new BadDataException("Project ID and User ID are required"),
|
|
353
|
-
);
|
|
354
|
-
}
|
|
378
|
+
const oneuptimeRequest: OneUptimeRequest = req as OneUptimeRequest;
|
|
355
379
|
|
|
356
380
|
/*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
381
|
+
* The state this route signs is what the callback trusts to decide
|
|
382
|
+
* which project gets the installation, so it must only ever be
|
|
383
|
+
* issued to the logged-in user for a project they belong to. Taking
|
|
384
|
+
* the user id from a query parameter — as this route used to — let
|
|
385
|
+
* anyone mint a valid state for any (project, user) pair without
|
|
386
|
+
* even holding a session.
|
|
360
387
|
*/
|
|
361
|
-
const state: string = JSONWebToken.signJsonPayload(
|
|
362
|
-
{ projectId, userId },
|
|
363
|
-
3600, // 1 hour expiry
|
|
364
|
-
);
|
|
365
|
-
|
|
366
|
-
const callbackUrl: string = `${HomeClientUrl.toString()}api/github/auth/callback`;
|
|
367
|
-
const installUrl: string = `https://github.com/apps/${GitHubAppName}/installations/new?state=${encodeURIComponent(state)}&redirect_uri=${encodeURIComponent(callbackUrl)}`;
|
|
368
|
-
|
|
369
|
-
return Response.redirect(req, res, URL.fromString(installUrl));
|
|
370
|
-
} catch (error) {
|
|
371
|
-
logger.error(
|
|
372
|
-
"GitHub Install Redirect Error:",
|
|
373
|
-
getLogAttributesFromRequest(req as OneUptimeRequest),
|
|
374
|
-
);
|
|
375
|
-
logger.error(
|
|
376
|
-
error,
|
|
377
|
-
getLogAttributesFromRequest(req as OneUptimeRequest),
|
|
378
|
-
);
|
|
379
|
-
return Response.sendErrorResponse(
|
|
380
|
-
req,
|
|
381
|
-
res,
|
|
382
|
-
error instanceof Error
|
|
383
|
-
? new BadDataException(error.message)
|
|
384
|
-
: new BadDataException("An error occurred"),
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
},
|
|
388
|
-
);
|
|
389
|
-
|
|
390
|
-
// List repositories for an installation
|
|
391
|
-
router.get(
|
|
392
|
-
"/github/repositories/:projectId/:installationId",
|
|
393
|
-
UserMiddleware.getUserMiddleware,
|
|
394
|
-
async (req: ExpressRequest, res: ExpressResponse) => {
|
|
395
|
-
try {
|
|
396
|
-
const oneuptimeRequest: OneUptimeRequest = req as OneUptimeRequest;
|
|
397
|
-
|
|
398
|
-
// Require authentication
|
|
399
388
|
if (!oneuptimeRequest.userAuthorization) {
|
|
400
389
|
return Response.sendErrorResponse(
|
|
401
390
|
req,
|
|
402
391
|
res,
|
|
403
392
|
new NotAuthenticatedException(
|
|
404
|
-
"Authentication is required to
|
|
393
|
+
"Authentication is required to install the GitHub App.",
|
|
405
394
|
),
|
|
406
395
|
);
|
|
407
396
|
}
|
|
408
397
|
|
|
409
398
|
const projectId: string | undefined =
|
|
410
|
-
req.
|
|
411
|
-
const installationId: string | undefined =
|
|
412
|
-
req.params["installationId"]?.toString();
|
|
399
|
+
req.query["projectId"]?.toString();
|
|
413
400
|
|
|
414
401
|
if (!projectId) {
|
|
415
402
|
return Response.sendErrorResponse(
|
|
@@ -419,18 +406,12 @@ export default class GitHubAPI {
|
|
|
419
406
|
);
|
|
420
407
|
}
|
|
421
408
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
req,
|
|
425
|
-
res,
|
|
426
|
-
new BadDataException("Installation ID is required"),
|
|
427
|
-
);
|
|
428
|
-
}
|
|
409
|
+
const userId: string =
|
|
410
|
+
oneuptimeRequest.userAuthorization.userId.toString();
|
|
429
411
|
|
|
430
|
-
// Verify user has access to this project
|
|
431
412
|
const userTenantAccessPermission: UserTenantAccessPermission | null =
|
|
432
413
|
await AccessTokenService.getUserTenantAccessPermission(
|
|
433
|
-
|
|
414
|
+
new ObjectID(userId),
|
|
434
415
|
new ObjectID(projectId),
|
|
435
416
|
);
|
|
436
417
|
|
|
@@ -444,188 +425,23 @@ export default class GitHubAPI {
|
|
|
444
425
|
);
|
|
445
426
|
}
|
|
446
427
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
"GitHub List Repositories Error:",
|
|
456
|
-
getLogAttributesFromRequest(req as OneUptimeRequest),
|
|
457
|
-
);
|
|
458
|
-
logger.error(
|
|
459
|
-
error,
|
|
460
|
-
getLogAttributesFromRequest(req as OneUptimeRequest),
|
|
461
|
-
);
|
|
462
|
-
|
|
463
|
-
// Handle stale installation ID - clear it from the project and return specific error
|
|
464
|
-
if (error instanceof GitHubInstallationNotFoundError) {
|
|
465
|
-
const projectId: string | undefined =
|
|
466
|
-
req.params["projectId"]?.toString();
|
|
467
|
-
|
|
468
|
-
if (projectId) {
|
|
469
|
-
try {
|
|
470
|
-
// Clear the stale installation ID from the project
|
|
471
|
-
await ProjectService.updateOneById({
|
|
472
|
-
id: new ObjectID(projectId),
|
|
473
|
-
data: {
|
|
474
|
-
gitHubAppInstallationId: null as unknown as string,
|
|
475
|
-
},
|
|
476
|
-
props: {
|
|
477
|
-
isRoot: true,
|
|
478
|
-
},
|
|
479
|
-
});
|
|
480
|
-
|
|
481
|
-
logger.info(
|
|
482
|
-
`Cleared stale GitHub App installation ID from project ${projectId}`,
|
|
483
|
-
getLogAttributesFromRequest(req as OneUptimeRequest),
|
|
484
|
-
);
|
|
485
|
-
} catch (clearError) {
|
|
486
|
-
logger.error(
|
|
487
|
-
"Failed to clear stale installation ID from project:",
|
|
488
|
-
getLogAttributesFromRequest(req as OneUptimeRequest),
|
|
489
|
-
);
|
|
490
|
-
logger.error(
|
|
491
|
-
clearError,
|
|
492
|
-
getLogAttributesFromRequest(req as OneUptimeRequest),
|
|
493
|
-
);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
// Return the specific error so the frontend knows to prompt reinstallation
|
|
498
|
-
return Response.sendErrorResponse(req, res, error);
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
return Response.sendErrorResponse(
|
|
502
|
-
req,
|
|
503
|
-
res,
|
|
504
|
-
error instanceof Error
|
|
505
|
-
? new BadDataException(error.message)
|
|
506
|
-
: new BadDataException("An error occurred"),
|
|
428
|
+
/*
|
|
429
|
+
* Redirect to GitHub App installation page
|
|
430
|
+
* The state parameter is a signed JWT to prevent tampering
|
|
431
|
+
* It expires in 1 hour to limit the window for replay attacks
|
|
432
|
+
*/
|
|
433
|
+
const state: string = JSONWebToken.signJsonPayload(
|
|
434
|
+
{ projectId, userId },
|
|
435
|
+
3600, // 1 hour expiry
|
|
507
436
|
);
|
|
508
|
-
}
|
|
509
|
-
},
|
|
510
|
-
);
|
|
511
|
-
|
|
512
|
-
// Connect a repository to a project
|
|
513
|
-
router.post(
|
|
514
|
-
"/github/repository/connect",
|
|
515
|
-
UserMiddleware.getUserMiddleware,
|
|
516
|
-
async (req: ExpressRequest, res: ExpressResponse) => {
|
|
517
|
-
try {
|
|
518
|
-
const oneuptimeRequest: OneUptimeRequest = req as OneUptimeRequest;
|
|
519
|
-
|
|
520
|
-
// Require authentication
|
|
521
|
-
if (!oneuptimeRequest.userAuthorization) {
|
|
522
|
-
return Response.sendErrorResponse(
|
|
523
|
-
req,
|
|
524
|
-
res,
|
|
525
|
-
new NotAuthenticatedException(
|
|
526
|
-
"Authentication is required to connect a repository.",
|
|
527
|
-
),
|
|
528
|
-
);
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
const body: JSONObject = req.body;
|
|
532
|
-
|
|
533
|
-
const projectId: string | undefined = body["projectId"]?.toString();
|
|
534
|
-
const installationId: string | undefined =
|
|
535
|
-
body["installationId"]?.toString();
|
|
536
|
-
const repositoryName: string | undefined =
|
|
537
|
-
body["repositoryName"]?.toString();
|
|
538
|
-
const organizationName: string | undefined =
|
|
539
|
-
body["organizationName"]?.toString();
|
|
540
|
-
const name: string | undefined = body["name"]?.toString();
|
|
541
|
-
const defaultBranch: string | undefined =
|
|
542
|
-
body["defaultBranch"]?.toString();
|
|
543
|
-
const repositoryUrl: string | undefined =
|
|
544
|
-
body["repositoryUrl"]?.toString();
|
|
545
|
-
const description: string | undefined =
|
|
546
|
-
body["description"]?.toString();
|
|
547
437
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
req,
|
|
551
|
-
res,
|
|
552
|
-
new BadDataException("Project ID is required"),
|
|
553
|
-
);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
if (!installationId) {
|
|
557
|
-
return Response.sendErrorResponse(
|
|
558
|
-
req,
|
|
559
|
-
res,
|
|
560
|
-
new BadDataException("Installation ID is required"),
|
|
561
|
-
);
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
// Verify user has access to this project
|
|
565
|
-
const userTenantAccessPermission: UserTenantAccessPermission | null =
|
|
566
|
-
await AccessTokenService.getUserTenantAccessPermission(
|
|
567
|
-
oneuptimeRequest.userAuthorization.userId,
|
|
568
|
-
new ObjectID(projectId),
|
|
569
|
-
);
|
|
570
|
-
|
|
571
|
-
if (!userTenantAccessPermission) {
|
|
572
|
-
return Response.sendErrorResponse(
|
|
573
|
-
req,
|
|
574
|
-
res,
|
|
575
|
-
new NotAuthorizedException(
|
|
576
|
-
"You do not have access to this project.",
|
|
577
|
-
),
|
|
578
|
-
);
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
if (!repositoryName) {
|
|
582
|
-
return Response.sendErrorResponse(
|
|
583
|
-
req,
|
|
584
|
-
res,
|
|
585
|
-
new BadDataException("Repository name is required"),
|
|
586
|
-
);
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
if (!organizationName) {
|
|
590
|
-
return Response.sendErrorResponse(
|
|
591
|
-
req,
|
|
592
|
-
res,
|
|
593
|
-
new BadDataException("Organization name is required"),
|
|
594
|
-
);
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
// Create the code repository record
|
|
598
|
-
const codeRepository: CodeRepository = new CodeRepository();
|
|
599
|
-
codeRepository.projectId = new ObjectID(projectId);
|
|
600
|
-
codeRepository.name = name || `${organizationName}/${repositoryName}`;
|
|
601
|
-
codeRepository.repositoryHostedAt = CodeRepositoryType.GitHub;
|
|
602
|
-
codeRepository.organizationName = organizationName;
|
|
603
|
-
codeRepository.repositoryName = repositoryName;
|
|
604
|
-
codeRepository.mainBranchName = defaultBranch || "main";
|
|
605
|
-
codeRepository.gitHubAppInstallationId = installationId;
|
|
606
|
-
|
|
607
|
-
if (repositoryUrl) {
|
|
608
|
-
codeRepository.repositoryUrl = URL.fromString(repositoryUrl);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
if (description) {
|
|
612
|
-
codeRepository.description = description;
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
const createdRepository: CodeRepository =
|
|
616
|
-
await CodeRepositoryService.create({
|
|
617
|
-
data: codeRepository,
|
|
618
|
-
props: {
|
|
619
|
-
isRoot: true,
|
|
620
|
-
},
|
|
621
|
-
});
|
|
438
|
+
const callbackUrl: string = `${HomeClientUrl.toString()}api/github/auth/callback`;
|
|
439
|
+
const installUrl: string = `https://github.com/apps/${GitHubAppName}/installations/new?state=${encodeURIComponent(state)}&redirect_uri=${encodeURIComponent(callbackUrl)}`;
|
|
622
440
|
|
|
623
|
-
return Response.
|
|
624
|
-
repository: BaseModel.toJSON(createdRepository, CodeRepository),
|
|
625
|
-
} as JSONObject);
|
|
441
|
+
return Response.redirect(req, res, URL.fromString(installUrl));
|
|
626
442
|
} catch (error) {
|
|
627
443
|
logger.error(
|
|
628
|
-
"GitHub
|
|
444
|
+
"GitHub Install Redirect Error:",
|
|
629
445
|
getLogAttributesFromRequest(req as OneUptimeRequest),
|
|
630
446
|
);
|
|
631
447
|
logger.error(
|
|
@@ -643,6 +459,26 @@ export default class GitHubAPI {
|
|
|
643
459
|
},
|
|
644
460
|
);
|
|
645
461
|
|
|
462
|
+
/*
|
|
463
|
+
* GET /github/repositories/:projectId/:installationId and
|
|
464
|
+
* POST /github/repository/connect used to live here. Both are gone.
|
|
465
|
+
*
|
|
466
|
+
* Both took an installation ID straight from the caller and checked only
|
|
467
|
+
* that the caller could access the project THEY had named — a comparison
|
|
468
|
+
* the caller controls both sides of, since anyone can create a project and
|
|
469
|
+
* own it. The listing route would then return any installation's private
|
|
470
|
+
* repository list (an enumeration oracle over a small integer space), and
|
|
471
|
+
* the connect route would persist the caller's installation ID onto a
|
|
472
|
+
* CodeRepository row, which is exactly the self-asserted binding the
|
|
473
|
+
* repository-token endpoint later minted a `ghs_` token from.
|
|
474
|
+
*
|
|
475
|
+
* Nothing called them: repositories are imported automatically by the
|
|
476
|
+
* install callback below and kept in sync by the installation webhooks, so
|
|
477
|
+
* the binding is always established by GitHub rather than asserted by a
|
|
478
|
+
* client. There is no supported way to name an installation ID over the
|
|
479
|
+
* API any more, and that is deliberate — see GitHubInstallationBinding.
|
|
480
|
+
*/
|
|
481
|
+
|
|
646
482
|
// GitHub webhook handler
|
|
647
483
|
router.post(
|
|
648
484
|
"/github/webhook",
|