@oneuptime/common 12.0.28 → 12.0.30
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/DashboardDomain.ts +43 -0
- package/Models/DatabaseModels/Index.ts +11 -0
- package/Models/DatabaseModels/MonitorTemplate.ts +15 -3
- package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +43 -0
- package/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.ts +662 -0
- package/Models/DatabaseModels/ProjectOnCallCalendarFeed.ts +584 -0
- package/Models/DatabaseModels/StatusPageDomain.ts +43 -0
- package/Models/DatabaseModels/UserOnCallCalendarFeed.ts +546 -0
- package/Models/DatabaseModels/UserOnCallShiftReminder.ts +231 -0
- package/Models/DatabaseModels/UserOnCallShiftReminderLog.ts +331 -0
- package/Server/API/DashboardDomainAPI.ts +74 -0
- package/Server/API/MicrosoftTeamsAPI.ts +81 -180
- package/Server/API/OnCallCalendarAPI.ts +2194 -0
- package/Server/API/StatusPageDomainAPI.ts +74 -0
- package/Server/EnvironmentConfig.ts +138 -0
- package/Server/Infrastructure/OnCallCalendarFeedCache.ts +1050 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790200000000-AllowNullMonitorNameOnMonitorTemplate.ts +43 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790300000000-AddCertificateReissueRequestedAtToDomains.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790400000000-AddOnCallCalendarFeeds.ts +253 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/OnCallCalendarFeedRateLimit.ts +487 -0
- package/Server/Middleware/ProjectAuthorization.ts +6 -1
- package/Server/Services/DashboardDomainService.ts +131 -0
- package/Server/Services/Index.ts +12 -0
- package/Server/Services/LogPipelineProcessorService.ts +88 -0
- package/Server/Services/MonitorTemplateService.ts +70 -11
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +32 -0
- package/Server/Services/OnCallDutyPolicyScheduleCalendarFeedService.ts +260 -0
- package/Server/Services/OnCallDutyPolicyScheduleLayerService.ts +70 -3
- package/Server/Services/OnCallDutyPolicyScheduleLayerUserService.ts +138 -3
- package/Server/Services/OnCallDutyPolicyScheduleService.ts +1465 -134
- package/Server/Services/OnCallDutyPolicyUserOverrideService.ts +167 -31
- package/Server/Services/ProjectOnCallCalendarFeedService.ts +192 -0
- package/Server/Services/StatusPageDomainService.ts +163 -3
- package/Server/Services/StatusPagePrivateUserSessionService.ts +197 -56
- package/Server/Services/TeamMemberService.ts +489 -1
- package/Server/Services/TeamService.ts +50 -0
- package/Server/Services/UserNotificationSettingService.ts +44 -1
- package/Server/Services/UserOnCallCalendarFeedService.ts +159 -0
- package/Server/Services/UserOnCallShiftReminderLogService.ts +151 -0
- package/Server/Services/UserOnCallShiftReminderService.ts +112 -0
- package/Server/Types/Domain.ts +17 -0
- package/Server/Utils/APIKey/AccessPermission.ts +24 -0
- package/Server/Utils/Greenlock/Greenlock.ts +156 -58
- package/Server/Utils/LogPipelineProcessorValidation.ts +112 -0
- package/Server/Utils/OnCall/CalendarFeedToken.ts +241 -0
- package/Server/Utils/OnCall/OnCallCalendarFeedRenderer.ts +1488 -0
- package/Server/Utils/OnCall/OnCallCalendarFeedUrls.ts +230 -0
- package/Server/Utils/OnCall/OnCallShiftChangeListeners.ts +227 -0
- package/Server/Utils/OnCall/OnCallShiftMaterializer.ts +1127 -0
- package/Server/Utils/OnCall/OnCallShiftReminderListener.ts +174 -0
- package/Server/Utils/OnCall/OnCallShiftReminderRunner.ts +2584 -0
- package/Server/Utils/Response.ts +134 -0
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.ts +1094 -45
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +153 -17
- package/Server/Utils/StartServer.ts +10 -0
- package/Server/Utils/Telemetry/AppMetrics.ts +51 -0
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +23 -11
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +0 -170
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Authorization.ts +158 -0
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +23 -11
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +35 -13
- package/Tests/App/Dashboard/MonitorTemplateColumnAndFacet.test.tsx +505 -0
- package/Tests/App/Dashboard/OnCallCalendarFeedLinks.test.tsx +229 -0
- package/Tests/App/Dashboard/OnCallCalendarFeedPlanGate.test.tsx +489 -0
- package/Tests/App/Dashboard/OnCallCalendarFeedSideMenus.test.tsx +149 -0
- package/Tests/App/Dashboard/OnCallCalendarFeedUtil.test.ts +855 -0
- package/Tests/App/Dashboard/OnCallPersonalCalendarFeed.test.tsx +1209 -0
- package/Tests/App/Dashboard/OnCallSharedCalendarFeedCard.test.tsx +1019 -0
- package/Tests/App/Dashboard/OnCallShiftRemindersAndUpcomingShifts.test.tsx +655 -0
- package/Tests/App/Dashboard/UserSettingsSetupChecklistModel.test.ts +73 -0
- package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +106 -0
- package/Tests/App/StatusPage/StatusPageLoginCodeUtil.test.ts +84 -0
- package/Tests/App/StatusPage/StatusPageRedirectSafety.test.ts +119 -0
- package/Tests/Models/MonitorTemplateMonitorNameColumn.test.ts +258 -0
- package/Tests/Models/OnCallCalendarFeedModels.test.ts +642 -0
- package/Tests/Models/OnCallDutyPolicyScheduleCalendarFeed.test.ts +288 -0
- package/Tests/Models/OnCallDutyPolicyScheduleShiftConfigVersion.test.ts +88 -0
- package/Tests/Models/UserOnCallShiftReminderModels.test.ts +368 -0
- package/Tests/Server/API/CustomDomainReissueSslAPI.test.ts +469 -0
- package/Tests/Server/API/Helpers.ts +8 -0
- package/Tests/Server/API/MicrosoftTeamsBotMessagesEndpoint.test.ts +729 -0
- package/Tests/Server/API/MicrosoftTeamsBotTestEndpoint.test.ts +26 -0
- package/Tests/Server/API/MicrosoftTeamsLegacyWebhookRemoval.test.ts +402 -0
- package/Tests/Server/API/OnCallCalendarAPI.test.ts +4461 -0
- package/Tests/Server/EnvironmentConfigOnCallCalendarFeed.test.ts +357 -0
- package/Tests/Server/Infrastructure/OnCallCalendarFeedCache.test.ts +1589 -0
- package/Tests/Server/Infrastructure/Postgres/AddOnCallCalendarFeedsMigration.test.ts +369 -0
- package/Tests/Server/Middleware/OnCallCalendarFeedRateLimit.test.ts +1365 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -0
- package/Tests/Server/Services/AddCertificateReissueRequestedAtToDomainsMigration.test.ts +287 -0
- package/Tests/Server/Services/CustomDomainCertificateReissue.test.ts +477 -0
- package/Tests/Server/Services/FeedRetentionConsistency.test.ts +70 -0
- package/Tests/Server/Services/LogPipelineProcessorSaveValidation.test.ts +249 -0
- package/Tests/Server/Services/MonitorTemplateServiceBulkSync.test.ts +549 -0
- package/Tests/Server/Services/MonitorTemplateServiceNetworkDeviceSync.test.ts +16 -3
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +57 -0
- package/Tests/Server/Services/OnCallCalendarFeedServices.test.ts +1103 -0
- package/Tests/Server/Services/OnCallDutyPolicyScheduleResolver.test.ts +1037 -0
- package/Tests/Server/Services/OnCallShiftConfigPropagation.test.ts +1270 -0
- package/Tests/Server/Services/SecurityEventLastErrorColumnWidth.test.ts +151 -15
- package/Tests/Server/Services/StatusPagePrivateUserSessionService.test.ts +587 -0
- package/Tests/Server/Services/TeamDeleteMemberCleanup.test.ts +156 -0
- package/Tests/Server/Services/TeamMemberOnCallCleanup.test.ts +755 -0
- package/Tests/Server/Services/UserNotificationSettingShiftReminderDefaults.test.ts +267 -0
- package/Tests/Server/Services/UserOnCallShiftReminderServices.test.ts +583 -0
- package/Tests/Server/Types/Database/Permissions/ApiKeyFileAccess.test.ts +286 -0
- package/Tests/Server/Types/Database/Permissions/MonitorTemplateColumnAccess.test.ts +328 -0
- package/Tests/Server/Types/Database/Permissions/OnCallCalendarFeedPermissions.test.ts +254 -0
- package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAndIsNull.test.ts +83 -0
- package/Tests/Server/Utils/AI/SRE/ConfidenceSignal.test.ts +377 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +16 -1
- package/Tests/Server/Utils/Greenlock/CertificateRenewalSchedule.test.ts +250 -0
- package/Tests/Server/Utils/LogPipelineProcessorValidation.test.ts +198 -0
- package/Tests/Server/Utils/OnCall/CalendarFeedToken.test.ts +467 -0
- package/Tests/Server/Utils/OnCall/OnCallCalendarFeedRenderer.test.ts +2142 -0
- package/Tests/Server/Utils/OnCall/OnCallCalendarFeedUrls.test.ts +278 -0
- package/Tests/Server/Utils/OnCall/OnCallResolverTestHarness.ts +440 -0
- package/Tests/Server/Utils/OnCall/OnCallShiftChangeListeners.test.ts +314 -0
- package/Tests/Server/Utils/OnCall/OnCallShiftMaterializer.test.ts +1502 -0
- package/Tests/Server/Utils/OnCall/OnCallShiftReminderListener.test.ts +491 -0
- package/Tests/Server/Utils/OnCall/OnCallShiftReminderRunner.test.ts +3088 -0
- package/Tests/Server/Utils/OnCall/OnCallShiftReminderTestHarness.ts +910 -0
- package/Tests/Server/Utils/ResponseSendCalendarResponse.test.ts +561 -0
- package/Tests/Server/Utils/SecurityEvent/ConnectorErrorMessage.test.ts +48 -9
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsAuth.test.ts +726 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClient.test.ts +74 -11
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsErrorHandling.test.ts +1107 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +20 -3
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +51 -11
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +1246 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsRequestContract.test.ts +961 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsResponseParsing.test.ts +653 -0
- package/Tests/Server/Utils/StartServerEncryptionSecretWarning.test.ts +64 -0
- package/Tests/Server/Utils/Telemetry/AppMetrics.test.ts +29 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsActionAuthorization.test.ts +880 -0
- package/Tests/Types/API/HTTPResponse.test.ts +175 -0
- package/Tests/Types/API/Route.test.ts +36 -4
- package/Tests/Types/Calendar/ICalendar.test.ts +488 -0
- package/Tests/Types/Database/DatabaseProperty.test.ts +171 -0
- package/Tests/Types/DateLocalShortDateTimeString.test.ts +518 -0
- package/Tests/Types/DateLocalTimeString.test.ts +259 -0
- package/Tests/Types/DateUserPrefers12HourFormat.test.ts +316 -0
- package/Tests/Types/NotificationSetting/NotificationSettingEventType.test.ts +53 -0
- package/Tests/Types/OnCallDutyPolicy/CalendarFeedTestFixtures.ts +310 -0
- package/Tests/Types/OnCallDutyPolicy/CalendarFeedWindow.test.ts +205 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilLayerMetaAndIterationCap.test.ts +458 -0
- package/Tests/Types/OnCallDutyPolicy/MaterializedShift.test.ts +197 -0
- package/Tests/Types/OnCallDutyPolicy/OnCallCalendarFeedUtil.test.ts +1986 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleShiftUtilGroupKey.test.ts +678 -0
- package/Tests/Types/OnCallDutyPolicy/ShiftSeamUtil.test.ts +417 -0
- package/Tests/UI/Components/LogsHistogram.test.tsx +41 -2
- package/Tests/UI/Components/LogsViewerEmptyStateTimeRange.test.tsx +212 -0
- package/Tests/UI/Components/TelemetryChartClockFormat.test.tsx +359 -0
- package/Tests/UI/Components/TimeRangePickerClockFormat.test.tsx +422 -0
- package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +146 -8
- package/Tests/UI/MicrosoftTeams/MicrosoftTeamsMessagingEndpointGuidance.test.tsx +520 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
- package/Tests/UI/Utils/Navigation.test.ts +82 -0
- package/Tests/Utils/Array.test.ts +100 -0
- package/Tests/Utils/CertificateReissue.test.ts +225 -0
- package/Tests/Utils/Grok/Grok.test.ts +492 -0
- package/Tests/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.test.ts +181 -13
- package/Types/API/Route.ts +20 -5
- package/Types/Calendar/ICalendar.ts +442 -0
- package/Types/Date.ts +143 -13
- package/Types/Email/EmailTemplateType.ts +2 -0
- package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
- package/Types/OnCallDutyPolicy/CalendarFeedWindow.ts +140 -0
- package/Types/OnCallDutyPolicy/Layer.ts +190 -35
- package/Types/OnCallDutyPolicy/MaterializedShift.ts +274 -0
- package/Types/OnCallDutyPolicy/OnCallCalendarFeedUtil.ts +1415 -0
- package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +159 -4
- package/Types/OnCallDutyPolicy/ShiftSeamUtil.ts +106 -0
- package/Types/Rum/SessionReplay.ts +62 -1
- package/UI/Components/Date/TimeRangePickerDropdown.tsx +9 -5
- package/UI/Components/LogsViewer/LogsViewer.tsx +12 -7
- package/UI/Components/LogsViewer/components/HistogramTooltip.tsx +18 -17
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +21 -28
- package/UI/Components/LogsViewer/components/LogsHistogram.tsx +2 -4
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +2 -4
- package/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.tsx +17 -16
- package/UI/Utils/Navigation.ts +42 -0
- package/Utils/Array.ts +37 -0
- package/Utils/CertificateReissue.ts +128 -0
- package/Utils/Grok/Grok.ts +461 -0
- package/Utils/Grok/GrokPatterns.ts +118 -0
- package/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.ts +58 -6
- package/build/dist/Models/DatabaseModels/DashboardDomain.js +44 -0
- package/build/dist/Models/DatabaseModels/DashboardDomain.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +11 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorTemplate.js +17 -4
- package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +44 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js +699 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js +620 -0
- package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js.map +1 -0
- package/build/dist/Models/DatabaseModels/StatusPageDomain.js +44 -0
- package/build/dist/Models/DatabaseModels/StatusPageDomain.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js +585 -0
- package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserOnCallShiftReminder.js +247 -0
- package/build/dist/Models/DatabaseModels/UserOnCallShiftReminder.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserOnCallShiftReminderLog.js +355 -0
- package/build/dist/Models/DatabaseModels/UserOnCallShiftReminderLog.js.map +1 -0
- package/build/dist/Server/API/DashboardDomainAPI.js +43 -1
- package/build/dist/Server/API/DashboardDomainAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +74 -118
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallCalendarAPI.js +1371 -0
- package/build/dist/Server/API/OnCallCalendarAPI.js.map +1 -0
- package/build/dist/Server/API/StatusPageDomainAPI.js +43 -1
- package/build/dist/Server/API/StatusPageDomainAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +102 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/OnCallCalendarFeedCache.js +663 -0
- package/build/dist/Server/Infrastructure/OnCallCalendarFeedCache.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790200000000-AllowNullMonitorNameOnMonitorTemplate.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790200000000-AllowNullMonitorNameOnMonitorTemplate.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790300000000-AddCertificateReissueRequestedAtToDomains.js +28 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790300000000-AddCertificateReissueRequestedAtToDomains.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790400000000-AddOnCallCalendarFeeds.js +103 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790400000000-AddOnCallCalendarFeeds.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/OnCallCalendarFeedRateLimit.js +342 -0
- package/build/dist/Server/Middleware/OnCallCalendarFeedRateLimit.js.map +1 -0
- package/build/dist/Server/Middleware/ProjectAuthorization.js +6 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Services/DashboardDomainService.js +104 -0
- package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +12 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/LogPipelineProcessorService.js +65 -0
- package/build/dist/Server/Services/LogPipelineProcessorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +57 -11
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +20 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleCalendarFeedService.js +219 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleCalendarFeedService.js.map +1 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js +47 -3
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js +112 -3
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +955 -9
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js +93 -6
- package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js.map +1 -1
- package/build/dist/Server/Services/ProjectOnCallCalendarFeedService.js +157 -0
- package/build/dist/Server/Services/ProjectOnCallCalendarFeedService.js.map +1 -0
- package/build/dist/Server/Services/StatusPageDomainService.js +132 -3
- package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserSessionService.js +112 -32
- package/build/dist/Server/Services/StatusPagePrivateUserSessionService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +396 -1
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TeamService.js +43 -0
- package/build/dist/Server/Services/TeamService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationSettingService.js +26 -1
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserOnCallCalendarFeedService.js +140 -0
- package/build/dist/Server/Services/UserOnCallCalendarFeedService.js.map +1 -0
- package/build/dist/Server/Services/UserOnCallShiftReminderLogService.js +116 -0
- package/build/dist/Server/Services/UserOnCallShiftReminderLogService.js.map +1 -0
- package/build/dist/Server/Services/UserOnCallShiftReminderService.js +92 -0
- package/build/dist/Server/Services/UserOnCallShiftReminderService.js.map +1 -0
- package/build/dist/Server/Types/Domain.js +16 -0
- package/build/dist/Server/Types/Domain.js.map +1 -1
- package/build/dist/Server/Utils/APIKey/AccessPermission.js +24 -0
- package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
- package/build/dist/Server/Utils/Greenlock/Greenlock.js +110 -35
- package/build/dist/Server/Utils/Greenlock/Greenlock.js.map +1 -1
- package/build/dist/Server/Utils/LogPipelineProcessorValidation.js +77 -0
- package/build/dist/Server/Utils/LogPipelineProcessorValidation.js.map +1 -0
- package/build/dist/Server/Utils/OnCall/CalendarFeedToken.js +161 -0
- package/build/dist/Server/Utils/OnCall/CalendarFeedToken.js.map +1 -0
- package/build/dist/Server/Utils/OnCall/OnCallCalendarFeedRenderer.js +983 -0
- package/build/dist/Server/Utils/OnCall/OnCallCalendarFeedRenderer.js.map +1 -0
- package/build/dist/Server/Utils/OnCall/OnCallCalendarFeedUrls.js +155 -0
- package/build/dist/Server/Utils/OnCall/OnCallCalendarFeedUrls.js.map +1 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftChangeListeners.js +145 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftChangeListeners.js.map +1 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftMaterializer.js +752 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftMaterializer.js.map +1 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftReminderListener.js +92 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftReminderListener.js.map +1 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js +1786 -0
- package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js.map +1 -0
- package/build/dist/Server/Utils/Response.js +97 -0
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js +777 -36
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +108 -17
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +9 -1
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/AppMetrics.js +41 -0
- package/build/dist/Server/Utils/Telemetry/AppMetrics.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +17 -6
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +0 -159
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Authorization.js +128 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Authorization.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +17 -6
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +25 -13
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/API/Route.js +16 -5
- package/build/dist/Types/API/Route.js.map +1 -1
- package/build/dist/Types/Calendar/ICalendar.js +290 -0
- package/build/dist/Types/Calendar/ICalendar.js.map +1 -0
- package/build/dist/Types/Date.js +115 -13
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +2 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
- package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/CalendarFeedWindow.js +97 -0
- package/build/dist/Types/OnCallDutyPolicy/CalendarFeedWindow.js.map +1 -0
- package/build/dist/Types/OnCallDutyPolicy/Layer.js +113 -19
- package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/MaterializedShift.js +134 -0
- package/build/dist/Types/OnCallDutyPolicy/MaterializedShift.js.map +1 -0
- package/build/dist/Types/OnCallDutyPolicy/OnCallCalendarFeedUtil.js +800 -0
- package/build/dist/Types/OnCallDutyPolicy/OnCallCalendarFeedUtil.js.map +1 -0
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +97 -3
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/ShiftSeamUtil.js +77 -0
- package/build/dist/Types/OnCallDutyPolicy/ShiftSeamUtil.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplay.js +38 -0
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +9 -5
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +12 -7
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/HistogramTooltip.js +15 -14
- package/build/dist/UI/Components/LogsViewer/components/HistogramTooltip.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +17 -22
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +2 -4
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +2 -4
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.js +15 -14
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js +30 -0
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/Utils/Array.js +25 -0
- package/build/dist/Utils/Array.js.map +1 -1
- package/build/dist/Utils/CertificateReissue.js +97 -0
- package/build/dist/Utils/CertificateReissue.js.map +1 -0
- package/build/dist/Utils/Grok/Grok.js +324 -0
- package/build/dist/Utils/Grok/Grok.js.map +1 -0
- package/build/dist/Utils/Grok/GrokPatterns.js +112 -0
- package/build/dist/Utils/Grok/GrokPatterns.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js +63 -3
- package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js.map +1 -1
- package/package.json +1 -1
- package/UI/Utils/JsonWebToken.ts +0 -14
- package/build/dist/UI/Utils/JsonWebToken.js +0 -10
- package/build/dist/UI/Utils/JsonWebToken.js.map +0 -1
|
@@ -27,7 +27,7 @@ import Route from "../../Types/API/Route";
|
|
|
27
27
|
import SubscriptionPlan, {
|
|
28
28
|
PlanType,
|
|
29
29
|
} from "../../Types/Billing/SubscriptionPlan";
|
|
30
|
-
import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
30
|
+
import LIMIT_MAX, { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
31
31
|
import Email from "../../Types/Email";
|
|
32
32
|
import EmailTemplateType from "../../Types/Email/EmailTemplateType";
|
|
33
33
|
import Name from "../../Types/Name";
|
|
@@ -41,6 +41,33 @@ import OnCallDutyPolicyTimeLogService from "./OnCallDutyPolicyTimeLogService";
|
|
|
41
41
|
import OneUptimeDate from "../../Types/Date";
|
|
42
42
|
import ProjectSCIMService from "./ProjectSCIMService";
|
|
43
43
|
import InMemoryTTLCache from "../Infrastructure/InMemoryTTLCache";
|
|
44
|
+
import OnCallDutyPolicyScheduleService from "./OnCallDutyPolicyScheduleService";
|
|
45
|
+
import OnCallDutyPolicyScheduleLayerUserService from "./OnCallDutyPolicyScheduleLayerUserService";
|
|
46
|
+
import OnCallDutyPolicyEscalationRuleUserService from "./OnCallDutyPolicyEscalationRuleUserService";
|
|
47
|
+
import OnCallDutyPolicyUserOverrideService from "./OnCallDutyPolicyUserOverrideService";
|
|
48
|
+
import UserOnCallCalendarFeedService from "./UserOnCallCalendarFeedService";
|
|
49
|
+
import UserOnCallShiftReminderService from "./UserOnCallShiftReminderService";
|
|
50
|
+
import OnCallDutyPolicyScheduleCalendarFeedService from "./OnCallDutyPolicyScheduleCalendarFeedService";
|
|
51
|
+
import ProjectOnCallCalendarFeedService from "./ProjectOnCallCalendarFeedService";
|
|
52
|
+
import OnCallCalendarFeedCache from "../Infrastructure/OnCallCalendarFeedCache";
|
|
53
|
+
import { OnCallShiftChangeReason } from "../Utils/OnCall/OnCallShiftChangeListeners";
|
|
54
|
+
import OnCallDutyPolicyScheduleLayerUser from "../../Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser";
|
|
55
|
+
|
|
56
|
+
/*
|
|
57
|
+
* What cleanupOnCallAssignmentsForUserLeavingProject did, for logging and
|
|
58
|
+
* for the tests. Every count is "as far as we got": a step that failed is
|
|
59
|
+
* logged and the remaining steps still run.
|
|
60
|
+
*/
|
|
61
|
+
export interface OnCallLeaveCleanupResult {
|
|
62
|
+
removedLayerUserCount: number;
|
|
63
|
+
removedEscalationRuleUserCount: number;
|
|
64
|
+
removedUserOverrideCount: number;
|
|
65
|
+
refreshedScheduleIds: Array<string>;
|
|
66
|
+
personalFeedDisabled: boolean;
|
|
67
|
+
removedReminderCount: number;
|
|
68
|
+
rotatedScheduleFeedIds: Array<string>;
|
|
69
|
+
rotatedProjectFeedIds: Array<string>;
|
|
70
|
+
}
|
|
44
71
|
|
|
45
72
|
export class TeamMemberService extends DatabaseService<TeamMember> {
|
|
46
73
|
/*
|
|
@@ -595,11 +622,51 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
|
|
|
595
622
|
protected override async onDeleteSuccess(
|
|
596
623
|
onDelete: OnDelete<TeamMember>,
|
|
597
624
|
): Promise<OnDelete<TeamMember>> {
|
|
625
|
+
/*
|
|
626
|
+
* remove-user-from-project deletes every membership of one user in one
|
|
627
|
+
* deleteBy, so the same (user, project) can appear several times here;
|
|
628
|
+
* the on-call cleanup is idempotent but not free, so run it once.
|
|
629
|
+
*/
|
|
630
|
+
const onCallCleanupDone: Set<string> = new Set<string>();
|
|
631
|
+
|
|
632
|
+
/*
|
|
633
|
+
* Whether ANY of the deleted rows for a (user, project) was an ACCEPTED
|
|
634
|
+
* membership. Revoking a pending invitation also brings the accepted
|
|
635
|
+
* count to zero, but someone who never accepted never had feed access —
|
|
636
|
+
* rotating every opted-in shared feed for that would clear each
|
|
637
|
+
* teammate's subscribed calendar for nothing (see
|
|
638
|
+
* cleanupOnCallAssignmentsIfUserLeftProject).
|
|
639
|
+
*/
|
|
640
|
+
const acceptedMembershipKeys: Set<string> = new Set<string>();
|
|
641
|
+
for (const item of onDelete.carryForward as Array<TeamMember>) {
|
|
642
|
+
if (item.hasAcceptedInvitation && item.userId && item.projectId) {
|
|
643
|
+
acceptedMembershipKeys.add(
|
|
644
|
+
`${item.userId.toString()}:${item.projectId.toString()}`,
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
598
649
|
for (const item of onDelete.carryForward as Array<TeamMember>) {
|
|
599
650
|
await this.refreshTokens(item.userId!, item.projectId!);
|
|
600
651
|
await this.updateSubscriptionSeatsByUniqueTeamMembersInProject(
|
|
601
652
|
item.projectId!,
|
|
602
653
|
);
|
|
654
|
+
|
|
655
|
+
/*
|
|
656
|
+
* Before the notification settings go: the "removed from on-call
|
|
657
|
+
* policy" notices the cleanup triggers should still reach the person,
|
|
658
|
+
* exactly as they would for a manual removal.
|
|
659
|
+
*/
|
|
660
|
+
const cleanupKey: string = `${item.userId?.toString()}:${item.projectId?.toString()}`;
|
|
661
|
+
if (!onCallCleanupDone.has(cleanupKey) && item.userId && item.projectId) {
|
|
662
|
+
onCallCleanupDone.add(cleanupKey);
|
|
663
|
+
await this.cleanupOnCallAssignmentsIfUserLeftProject({
|
|
664
|
+
projectId: item.projectId,
|
|
665
|
+
userId: item.userId,
|
|
666
|
+
hadAcceptedMembership: acceptedMembershipKeys.has(cleanupKey),
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
|
|
603
670
|
await UserNotificationSettingService.removeDefaultNotificationSettingsForUser(
|
|
604
671
|
item.userId!,
|
|
605
672
|
item.projectId!,
|
|
@@ -609,6 +676,427 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
|
|
|
609
676
|
return onDelete;
|
|
610
677
|
}
|
|
611
678
|
|
|
679
|
+
/**
|
|
680
|
+
* Run the on-call cleanup when — and only when — the user no longer holds
|
|
681
|
+
* an accepted membership in ANY team of the project: the same rule
|
|
682
|
+
* removeDefaultNotificationSettingsForUser applies. A user who merely left
|
|
683
|
+
* one of several teams keeps every on-call assignment. Best-effort: never
|
|
684
|
+
* throws into the delete path.
|
|
685
|
+
*
|
|
686
|
+
* hadAcceptedMembership (default true): whether the membership rows that
|
|
687
|
+
* were just deleted included an ACCEPTED one. Revoking a never-accepted
|
|
688
|
+
* invitation passes false — the row cleanup still runs, but the opted-in
|
|
689
|
+
* shared feeds are NOT rotated: the invitee never had the links or any
|
|
690
|
+
* access, and rotation would silently clear every teammate's subscribed
|
|
691
|
+
* calendar.
|
|
692
|
+
*/
|
|
693
|
+
@CaptureSpan()
|
|
694
|
+
public async cleanupOnCallAssignmentsIfUserLeftProject(data: {
|
|
695
|
+
projectId: ObjectID;
|
|
696
|
+
userId: ObjectID;
|
|
697
|
+
hadAcceptedMembership?: boolean | undefined;
|
|
698
|
+
}): Promise<OnCallLeaveCleanupResult | null> {
|
|
699
|
+
try {
|
|
700
|
+
const remaining: PositiveNumber = await this.countBy({
|
|
701
|
+
query: {
|
|
702
|
+
projectId: data.projectId,
|
|
703
|
+
userId: data.userId,
|
|
704
|
+
hasAcceptedInvitation: true,
|
|
705
|
+
},
|
|
706
|
+
props: {
|
|
707
|
+
isRoot: true,
|
|
708
|
+
},
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
if (remaining.toNumber() > 0) {
|
|
712
|
+
return null;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
return await this.cleanupOnCallAssignmentsForUserLeavingProject({
|
|
716
|
+
projectId: data.projectId,
|
|
717
|
+
userId: data.userId,
|
|
718
|
+
rotateSharedFeeds: data.hadAcceptedMembership !== false,
|
|
719
|
+
});
|
|
720
|
+
} catch (err) {
|
|
721
|
+
logger.error(
|
|
722
|
+
err as Error,
|
|
723
|
+
{
|
|
724
|
+
projectId: data.projectId.toString(),
|
|
725
|
+
userId: data.userId.toString(),
|
|
726
|
+
} as LogAttributes,
|
|
727
|
+
);
|
|
728
|
+
return null;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* A user who has left the project must stop being paged and must stop
|
|
734
|
+
* seeing the project's shifts. Nothing used to do this: their layer-user
|
|
735
|
+
* and escalation-rule-user rows survived, so schedules kept rotating onto
|
|
736
|
+
* an ex-member and policies kept escalating to them. In order:
|
|
737
|
+
*
|
|
738
|
+
* 1. delete the user's OnCallDutyPolicyScheduleLayerUser rows in the
|
|
739
|
+
* project (root; the layers' 1-based order is re-sequenced),
|
|
740
|
+
* 2. delete the user's OnCallDutyPolicyEscalationRuleUser rows through
|
|
741
|
+
* the service, so its hooks close the time logs, write the policy feed
|
|
742
|
+
* items and notify as a manual removal would,
|
|
743
|
+
* 3. delete the project's not-yet-ended OnCallDutyPolicyUserOverride rows
|
|
744
|
+
* that name the user on EITHER side (as the overridden user or as the
|
|
745
|
+
* substitute), through the service — an override "route my alerts to
|
|
746
|
+
* Bob" would keep paging a departed Bob, and "route Alice's alerts to
|
|
747
|
+
* me" would keep the departed user's covering shifts in the feeds and
|
|
748
|
+
* in /my-shifts; the service's hooks write the policy feed items,
|
|
749
|
+
* refresh the overridden colleagues' rosters and propagate,
|
|
750
|
+
* 4. re-resolve the roster of every affected schedule (this pages the
|
|
751
|
+
* person who is now on call — intended: who gets paged changed),
|
|
752
|
+
* 5. bump those schedules' shiftConfigVersion, purge the feed caches and
|
|
753
|
+
* notify the shift-change listeners (reminders re-plan),
|
|
754
|
+
* 6. disable — not delete — the user's personal calendar feed for the
|
|
755
|
+
* project, so their subscribed calendar clears itself,
|
|
756
|
+
* 7. delete the user's shift reminders in the project,
|
|
757
|
+
* 8. rotate every enabled schedule / project feed that opted into
|
|
758
|
+
* rotateWhenMemberLeaves, and purge the project's feed bodies —
|
|
759
|
+
* skipped when rotateSharedFeeds is false (a revoked never-accepted
|
|
760
|
+
* invitation: the invitee never had the links).
|
|
761
|
+
*
|
|
762
|
+
* Each step is isolated: a failure is logged and the next step still runs.
|
|
763
|
+
* Unconditional — callers decide whether the user really left (see
|
|
764
|
+
* cleanupOnCallAssignmentsIfUserLeftProject).
|
|
765
|
+
*/
|
|
766
|
+
@CaptureSpan()
|
|
767
|
+
public async cleanupOnCallAssignmentsForUserLeavingProject(data: {
|
|
768
|
+
projectId: ObjectID;
|
|
769
|
+
userId: ObjectID;
|
|
770
|
+
rotateSharedFeeds?: boolean | undefined;
|
|
771
|
+
}): Promise<OnCallLeaveCleanupResult> {
|
|
772
|
+
const { projectId, userId } = data;
|
|
773
|
+
|
|
774
|
+
const logAttributes: LogAttributes = {
|
|
775
|
+
projectId: projectId.toString(),
|
|
776
|
+
userId: userId.toString(),
|
|
777
|
+
} as LogAttributes;
|
|
778
|
+
|
|
779
|
+
const result: OnCallLeaveCleanupResult = {
|
|
780
|
+
removedLayerUserCount: 0,
|
|
781
|
+
removedEscalationRuleUserCount: 0,
|
|
782
|
+
removedUserOverrideCount: 0,
|
|
783
|
+
refreshedScheduleIds: [],
|
|
784
|
+
personalFeedDisabled: false,
|
|
785
|
+
removedReminderCount: 0,
|
|
786
|
+
rotatedScheduleFeedIds: [],
|
|
787
|
+
rotatedProjectFeedIds: [],
|
|
788
|
+
};
|
|
789
|
+
|
|
790
|
+
const affectedScheduleIds: Array<ObjectID> = [];
|
|
791
|
+
const affectedLayerIds: Array<ObjectID> = [];
|
|
792
|
+
|
|
793
|
+
// 1. Layer-user rows.
|
|
794
|
+
try {
|
|
795
|
+
const layerUsers: Array<OnCallDutyPolicyScheduleLayerUser> =
|
|
796
|
+
await OnCallDutyPolicyScheduleLayerUserService.findBy({
|
|
797
|
+
query: {
|
|
798
|
+
projectId,
|
|
799
|
+
userId,
|
|
800
|
+
},
|
|
801
|
+
select: {
|
|
802
|
+
_id: true,
|
|
803
|
+
onCallDutyPolicyScheduleId: true,
|
|
804
|
+
onCallDutyPolicyScheduleLayerId: true,
|
|
805
|
+
},
|
|
806
|
+
limit: LIMIT_PER_PROJECT,
|
|
807
|
+
skip: 0,
|
|
808
|
+
props: {
|
|
809
|
+
isRoot: true,
|
|
810
|
+
},
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
const seenSchedules: Set<string> = new Set<string>();
|
|
814
|
+
const seenLayers: Set<string> = new Set<string>();
|
|
815
|
+
|
|
816
|
+
for (const row of layerUsers) {
|
|
817
|
+
const scheduleId: string | undefined =
|
|
818
|
+
row.onCallDutyPolicyScheduleId?.toString();
|
|
819
|
+
if (scheduleId && !seenSchedules.has(scheduleId)) {
|
|
820
|
+
seenSchedules.add(scheduleId);
|
|
821
|
+
affectedScheduleIds.push(row.onCallDutyPolicyScheduleId!);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
const layerId: string | undefined =
|
|
825
|
+
row.onCallDutyPolicyScheduleLayerId?.toString();
|
|
826
|
+
if (layerId && !seenLayers.has(layerId)) {
|
|
827
|
+
seenLayers.add(layerId);
|
|
828
|
+
affectedLayerIds.push(row.onCallDutyPolicyScheduleLayerId!);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
if (layerUsers.length > 0) {
|
|
833
|
+
result.removedLayerUserCount =
|
|
834
|
+
await OnCallDutyPolicyScheduleLayerUserService.deleteBy({
|
|
835
|
+
query: {
|
|
836
|
+
projectId,
|
|
837
|
+
userId,
|
|
838
|
+
},
|
|
839
|
+
limit: LIMIT_PER_PROJECT,
|
|
840
|
+
skip: 0,
|
|
841
|
+
props: {
|
|
842
|
+
isRoot: true,
|
|
843
|
+
},
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
for (const layerId of affectedLayerIds) {
|
|
847
|
+
try {
|
|
848
|
+
await OnCallDutyPolicyScheduleLayerUserService.resequenceOrderInLayer(
|
|
849
|
+
layerId,
|
|
850
|
+
);
|
|
851
|
+
} catch (err) {
|
|
852
|
+
logger.error(err as Error, logAttributes);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
} catch (err) {
|
|
857
|
+
logger.error(
|
|
858
|
+
"Error removing on-call schedule layer users for a user who left the project (best-effort).",
|
|
859
|
+
logAttributes,
|
|
860
|
+
);
|
|
861
|
+
logger.error(err as Error, logAttributes);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
// 2. Escalation-rule user rows (through the service so its hooks run).
|
|
865
|
+
try {
|
|
866
|
+
const ruleUserCount: PositiveNumber =
|
|
867
|
+
await OnCallDutyPolicyEscalationRuleUserService.countBy({
|
|
868
|
+
query: {
|
|
869
|
+
projectId,
|
|
870
|
+
userId,
|
|
871
|
+
},
|
|
872
|
+
props: {
|
|
873
|
+
isRoot: true,
|
|
874
|
+
},
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
if (ruleUserCount.toNumber() > 0) {
|
|
878
|
+
result.removedEscalationRuleUserCount =
|
|
879
|
+
await OnCallDutyPolicyEscalationRuleUserService.deleteBy({
|
|
880
|
+
query: {
|
|
881
|
+
projectId,
|
|
882
|
+
userId,
|
|
883
|
+
},
|
|
884
|
+
limit: LIMIT_PER_PROJECT,
|
|
885
|
+
skip: 0,
|
|
886
|
+
props: {
|
|
887
|
+
isRoot: true,
|
|
888
|
+
},
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
} catch (err) {
|
|
892
|
+
logger.error(
|
|
893
|
+
"Error removing escalation-rule users for a user who left the project (best-effort).",
|
|
894
|
+
logAttributes,
|
|
895
|
+
);
|
|
896
|
+
logger.error(err as Error, logAttributes);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
/*
|
|
900
|
+
* 3. Not-yet-ended user overrides that name the user on either side.
|
|
901
|
+
* Deleted THROUGH the service so its hooks write the policy feed
|
|
902
|
+
* items, refresh the overridden colleagues' rosters and propagate
|
|
903
|
+
* (version bump, cache purge, reminder re-plan). Ended overrides are
|
|
904
|
+
* history and stay. overrideUserId and routeAlertsToUserId can never
|
|
905
|
+
* be the same user (enforced on create), so the two deletes are
|
|
906
|
+
* disjoint.
|
|
907
|
+
*/
|
|
908
|
+
try {
|
|
909
|
+
const now: Date = OneUptimeDate.getCurrentDate();
|
|
910
|
+
|
|
911
|
+
result.removedUserOverrideCount +=
|
|
912
|
+
await OnCallDutyPolicyUserOverrideService.deleteBy({
|
|
913
|
+
query: {
|
|
914
|
+
projectId,
|
|
915
|
+
overrideUserId: userId,
|
|
916
|
+
endsAt: QueryHelper.greaterThan(now),
|
|
917
|
+
},
|
|
918
|
+
limit: LIMIT_PER_PROJECT,
|
|
919
|
+
skip: 0,
|
|
920
|
+
props: {
|
|
921
|
+
isRoot: true,
|
|
922
|
+
},
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
result.removedUserOverrideCount +=
|
|
926
|
+
await OnCallDutyPolicyUserOverrideService.deleteBy({
|
|
927
|
+
query: {
|
|
928
|
+
projectId,
|
|
929
|
+
routeAlertsToUserId: userId,
|
|
930
|
+
endsAt: QueryHelper.greaterThan(now),
|
|
931
|
+
},
|
|
932
|
+
limit: LIMIT_PER_PROJECT,
|
|
933
|
+
skip: 0,
|
|
934
|
+
props: {
|
|
935
|
+
isRoot: true,
|
|
936
|
+
},
|
|
937
|
+
});
|
|
938
|
+
} catch (err) {
|
|
939
|
+
logger.error(
|
|
940
|
+
"Error removing user overrides for a user who left the project (best-effort).",
|
|
941
|
+
logAttributes,
|
|
942
|
+
);
|
|
943
|
+
logger.error(err as Error, logAttributes);
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// 4. Rosters of the affected schedules.
|
|
947
|
+
for (const scheduleId of affectedScheduleIds) {
|
|
948
|
+
try {
|
|
949
|
+
await OnCallDutyPolicyScheduleService.refreshCurrentUserIdAndHandoffTimeInSchedule(
|
|
950
|
+
scheduleId,
|
|
951
|
+
);
|
|
952
|
+
result.refreshedScheduleIds.push(scheduleId.toString());
|
|
953
|
+
} catch (err) {
|
|
954
|
+
logger.error(
|
|
955
|
+
`Error refreshing the roster of schedule ${scheduleId.toString()} after a member left the project (best-effort).`,
|
|
956
|
+
logAttributes,
|
|
957
|
+
);
|
|
958
|
+
logger.error(err as Error, logAttributes);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
// 5. Version bump, cache purge, listeners (never throws).
|
|
963
|
+
await OnCallDutyPolicyScheduleService.propagateShiftConfigChange({
|
|
964
|
+
scheduleIds: affectedScheduleIds,
|
|
965
|
+
projectId,
|
|
966
|
+
userIds: [userId],
|
|
967
|
+
reason: OnCallShiftChangeReason.MemberLeftProject,
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
// 6. Personal calendar feed: disabled, not deleted.
|
|
971
|
+
try {
|
|
972
|
+
const feeds: PositiveNumber = await UserOnCallCalendarFeedService.countBy(
|
|
973
|
+
{
|
|
974
|
+
query: {
|
|
975
|
+
projectId,
|
|
976
|
+
userId,
|
|
977
|
+
},
|
|
978
|
+
props: {
|
|
979
|
+
isRoot: true,
|
|
980
|
+
},
|
|
981
|
+
},
|
|
982
|
+
);
|
|
983
|
+
|
|
984
|
+
if (feeds.toNumber() > 0) {
|
|
985
|
+
await UserOnCallCalendarFeedService.updateOneBy({
|
|
986
|
+
query: {
|
|
987
|
+
projectId,
|
|
988
|
+
userId,
|
|
989
|
+
},
|
|
990
|
+
data: {
|
|
991
|
+
isEnabled: false,
|
|
992
|
+
},
|
|
993
|
+
props: {
|
|
994
|
+
isRoot: true,
|
|
995
|
+
},
|
|
996
|
+
});
|
|
997
|
+
|
|
998
|
+
result.personalFeedDisabled = true;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
await OnCallCalendarFeedCache.purgeForUser(
|
|
1002
|
+
projectId.toString(),
|
|
1003
|
+
userId.toString(),
|
|
1004
|
+
);
|
|
1005
|
+
} catch (err) {
|
|
1006
|
+
logger.error(
|
|
1007
|
+
"Error disabling the personal calendar feed of a user who left the project (best-effort).",
|
|
1008
|
+
logAttributes,
|
|
1009
|
+
);
|
|
1010
|
+
logger.error(err as Error, logAttributes);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
// 7. Shift reminders.
|
|
1014
|
+
try {
|
|
1015
|
+
result.removedReminderCount =
|
|
1016
|
+
await UserOnCallShiftReminderService.deleteBy({
|
|
1017
|
+
query: {
|
|
1018
|
+
projectId,
|
|
1019
|
+
userId,
|
|
1020
|
+
},
|
|
1021
|
+
limit: LIMIT_PER_PROJECT,
|
|
1022
|
+
skip: 0,
|
|
1023
|
+
props: {
|
|
1024
|
+
isRoot: true,
|
|
1025
|
+
},
|
|
1026
|
+
});
|
|
1027
|
+
} catch (err) {
|
|
1028
|
+
logger.error(
|
|
1029
|
+
"Error removing shift reminders of a user who left the project (best-effort).",
|
|
1030
|
+
logAttributes,
|
|
1031
|
+
);
|
|
1032
|
+
logger.error(err as Error, logAttributes);
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
/*
|
|
1036
|
+
* 8. Shared feeds that opted into rotation on member leave. Skipped when
|
|
1037
|
+
* the caller says no ACCEPTED membership went away (a revoked pending
|
|
1038
|
+
* invitation): the invitee never had the links, and rotating would
|
|
1039
|
+
* clear every subscribed teammate's calendar for nothing.
|
|
1040
|
+
*/
|
|
1041
|
+
if (data.rotateSharedFeeds !== false) {
|
|
1042
|
+
try {
|
|
1043
|
+
const rotatedScheduleFeedIds: Array<ObjectID> =
|
|
1044
|
+
await OnCallDutyPolicyScheduleCalendarFeedService.rotateFeedsForMemberLeave(
|
|
1045
|
+
{ projectId },
|
|
1046
|
+
);
|
|
1047
|
+
|
|
1048
|
+
result.rotatedScheduleFeedIds = rotatedScheduleFeedIds.map(
|
|
1049
|
+
(id: ObjectID) => {
|
|
1050
|
+
return id.toString();
|
|
1051
|
+
},
|
|
1052
|
+
);
|
|
1053
|
+
} catch (err) {
|
|
1054
|
+
logger.error(
|
|
1055
|
+
"Error rotating schedule calendar feeds after a member left the project (best-effort).",
|
|
1056
|
+
logAttributes,
|
|
1057
|
+
);
|
|
1058
|
+
logger.error(err as Error, logAttributes);
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
try {
|
|
1062
|
+
const rotatedProjectFeedIds: Array<ObjectID> =
|
|
1063
|
+
await ProjectOnCallCalendarFeedService.rotateFeedsForMemberLeave({
|
|
1064
|
+
projectId,
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
result.rotatedProjectFeedIds = rotatedProjectFeedIds.map(
|
|
1068
|
+
(id: ObjectID) => {
|
|
1069
|
+
return id.toString();
|
|
1070
|
+
},
|
|
1071
|
+
);
|
|
1072
|
+
} catch (err) {
|
|
1073
|
+
logger.error(
|
|
1074
|
+
"Error rotating the project calendar feed after a member left the project (best-effort).",
|
|
1075
|
+
logAttributes,
|
|
1076
|
+
);
|
|
1077
|
+
logger.error(err as Error, logAttributes);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
if (
|
|
1081
|
+
result.rotatedScheduleFeedIds.length > 0 ||
|
|
1082
|
+
result.rotatedProjectFeedIds.length > 0
|
|
1083
|
+
) {
|
|
1084
|
+
try {
|
|
1085
|
+
await OnCallCalendarFeedCache.purgeForProject(projectId.toString());
|
|
1086
|
+
} catch (err) {
|
|
1087
|
+
logger.error(err as Error, logAttributes);
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
logger.debug(
|
|
1093
|
+
`On-call cleanup for a user leaving the project: ${JSON.stringify(result)}`,
|
|
1094
|
+
logAttributes,
|
|
1095
|
+
);
|
|
1096
|
+
|
|
1097
|
+
return result;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
612
1100
|
@CaptureSpan()
|
|
613
1101
|
public async getUniqueTeamMemberCountInProject(
|
|
614
1102
|
projectId: ObjectID,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import CreateBy from "../Types/Database/CreateBy";
|
|
2
2
|
import DeleteBy from "../Types/Database/DeleteBy";
|
|
3
3
|
import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
|
|
4
|
+
import QueryHelper from "../Types/Database/QueryHelper";
|
|
4
5
|
import UpdateBy from "../Types/Database/UpdateBy";
|
|
5
6
|
import DatabaseService from "./DatabaseService";
|
|
6
7
|
import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
@@ -12,6 +13,7 @@ import PositiveNumber from "../../Types/PositiveNumber";
|
|
|
12
13
|
import TeamMember from "../../Models/DatabaseModels/TeamMember";
|
|
13
14
|
import TeamMemberService from "./TeamMemberService";
|
|
14
15
|
import ProjectSCIMService from "./ProjectSCIMService";
|
|
16
|
+
import ModelPermission from "../Types/Database/Permissions/Index";
|
|
15
17
|
|
|
16
18
|
export class Service extends DatabaseService<Model> {
|
|
17
19
|
public constructor() {
|
|
@@ -156,6 +158,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
156
158
|
limit: LIMIT_MAX,
|
|
157
159
|
skip: 0,
|
|
158
160
|
select: {
|
|
161
|
+
_id: true,
|
|
159
162
|
name: true,
|
|
160
163
|
isTeamDeleteable: true,
|
|
161
164
|
projectId: true,
|
|
@@ -189,6 +192,53 @@ export class Service extends DatabaseService<Model> {
|
|
|
189
192
|
}
|
|
190
193
|
}
|
|
191
194
|
|
|
195
|
+
/*
|
|
196
|
+
* Delete these teams' memberships THROUGH TeamMemberService before the
|
|
197
|
+
* team rows go. The TeamMember.teamId FK is ON DELETE CASCADE, so leaving
|
|
198
|
+
* the rows to Postgres would remove them hook-free: no token refresh, no
|
|
199
|
+
* seat update, no notification-settings cleanup and no on-call cleanup —
|
|
200
|
+
* a user whose ONLY team was deleted kept their schedule-layer and
|
|
201
|
+
* escalation-rule assignments, their personal calendar feed stayed
|
|
202
|
+
* enabled and the rotateWhenMemberLeaves feeds were never rotated, so
|
|
203
|
+
* the schedule kept rotating onto (and paging) an ex-member. Runs after
|
|
204
|
+
* the guards above so a refused delete removes nobody. Mirrors the SCIM
|
|
205
|
+
* group-delete path, which already deletes members first for the same
|
|
206
|
+
* reason.
|
|
207
|
+
*/
|
|
208
|
+
const teamIds: Array<ObjectID> = teams
|
|
209
|
+
.map((team: Model) => {
|
|
210
|
+
return team.id;
|
|
211
|
+
})
|
|
212
|
+
.filter((teamId: ObjectID | null): teamId is ObjectID => {
|
|
213
|
+
return Boolean(teamId);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
if (teamIds.length > 0) {
|
|
217
|
+
/*
|
|
218
|
+
* DatabaseService checks DELETE permission AFTER this hook runs, and the
|
|
219
|
+
* lookup above only needed READ permission. Since we are about to delete
|
|
220
|
+
* rows on the caller's behalf, check the caller's delete permission on
|
|
221
|
+
* Team FIRST — otherwise someone who may read teams but not delete them
|
|
222
|
+
* would still wipe every membership before being refused. The framework
|
|
223
|
+
* re-runs the same check on the untouched query straight after, so this
|
|
224
|
+
* changes nothing for a caller who is allowed.
|
|
225
|
+
*/
|
|
226
|
+
await ModelPermission.checkDeleteQueryPermission(
|
|
227
|
+
Model,
|
|
228
|
+
deleteBy.query,
|
|
229
|
+
deleteBy.props,
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
await TeamMemberService.deleteBy({
|
|
233
|
+
query: {
|
|
234
|
+
teamId: QueryHelper.any(teamIds),
|
|
235
|
+
},
|
|
236
|
+
limit: LIMIT_MAX,
|
|
237
|
+
skip: 0,
|
|
238
|
+
props: { isRoot: true },
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
192
242
|
return { deleteBy, carryForward: null };
|
|
193
243
|
}
|
|
194
244
|
}
|
|
@@ -68,7 +68,13 @@ export class Service extends DatabaseService<UserNotificationSetting> {
|
|
|
68
68
|
smsMessage: SMSMessage;
|
|
69
69
|
callRequestMessage: CallRequestMessage;
|
|
70
70
|
pushNotificationMessage: PushNotificationMessage;
|
|
71
|
-
|
|
71
|
+
/*
|
|
72
|
+
* Optional: WhatsApp only delivers Meta-approved template payloads, so a
|
|
73
|
+
* caller whose event type has no registered template leaves this out and
|
|
74
|
+
* the channel is skipped (the body of this method already guards for it)
|
|
75
|
+
* instead of failing at the notification service.
|
|
76
|
+
*/
|
|
77
|
+
whatsAppMessage?: WhatsAppMessagePayload | undefined;
|
|
72
78
|
telegramMessage?: TelegramMessagePayload | undefined;
|
|
73
79
|
incidentId?: ObjectID | undefined;
|
|
74
80
|
alertId?: ObjectID | undefined;
|
|
@@ -846,6 +852,38 @@ export class Service extends DatabaseService<UserNotificationSetting> {
|
|
|
846
852
|
projectId,
|
|
847
853
|
NotificationSettingEventType.SEND_WHEN_USER_IS_NO_LONGER_ACTIVE_ON_ON_CALL_ROSTER,
|
|
848
854
|
);
|
|
855
|
+
|
|
856
|
+
await this.addShiftReminderNotificationSettings(userId, projectId);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/*
|
|
860
|
+
* The two shift-reminder events ("before my shift starts", "my upcoming
|
|
861
|
+
* shift is reassigned"). Email AND push on by default: a reminder that
|
|
862
|
+
* only lands in a mailbox is easy to miss at 05:45, and both are the
|
|
863
|
+
* user's own lead times, not a page. Idempotent — the
|
|
864
|
+
* AddShiftReminderNotificationSettingsForUsers data migration calls this
|
|
865
|
+
* for every existing member, and sendUserNotification sends nothing
|
|
866
|
+
* without a row, so this is what makes the reminder worker's output
|
|
867
|
+
* non-zero for users who joined before the events existed.
|
|
868
|
+
*/
|
|
869
|
+
@CaptureSpan()
|
|
870
|
+
public async addShiftReminderNotificationSettings(
|
|
871
|
+
userId: ObjectID,
|
|
872
|
+
projectId: ObjectID,
|
|
873
|
+
): Promise<void> {
|
|
874
|
+
await this.addNotificationSettingIfNotExists(
|
|
875
|
+
userId,
|
|
876
|
+
projectId,
|
|
877
|
+
NotificationSettingEventType.SEND_BEFORE_USER_ON_CALL_SHIFT_STARTS,
|
|
878
|
+
{ alertByPush: true },
|
|
879
|
+
);
|
|
880
|
+
|
|
881
|
+
await this.addNotificationSettingIfNotExists(
|
|
882
|
+
userId,
|
|
883
|
+
projectId,
|
|
884
|
+
NotificationSettingEventType.SEND_WHEN_USER_ON_CALL_SHIFT_IS_REASSIGNED,
|
|
885
|
+
{ alertByPush: true },
|
|
886
|
+
);
|
|
849
887
|
}
|
|
850
888
|
|
|
851
889
|
private async addAlertNotificationSettings(
|
|
@@ -940,6 +978,7 @@ export class Service extends DatabaseService<UserNotificationSetting> {
|
|
|
940
978
|
userId: ObjectID,
|
|
941
979
|
projectId: ObjectID,
|
|
942
980
|
eventType: NotificationSettingEventType,
|
|
981
|
+
options?: { alertByPush?: boolean | undefined },
|
|
943
982
|
): Promise<void> {
|
|
944
983
|
const existingNotification: PositiveNumber = await this.countBy({
|
|
945
984
|
query: {
|
|
@@ -959,6 +998,10 @@ export class Service extends DatabaseService<UserNotificationSetting> {
|
|
|
959
998
|
item.eventType = eventType;
|
|
960
999
|
item.alertByEmail = true;
|
|
961
1000
|
|
|
1001
|
+
if (options?.alertByPush) {
|
|
1002
|
+
item.alertByPush = true;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
962
1005
|
await this.create({
|
|
963
1006
|
data: item,
|
|
964
1007
|
props: {
|