@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.
Files changed (367) hide show
  1. package/Models/DatabaseModels/DashboardDomain.ts +43 -0
  2. package/Models/DatabaseModels/Index.ts +11 -0
  3. package/Models/DatabaseModels/MonitorTemplate.ts +15 -3
  4. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +43 -0
  5. package/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.ts +662 -0
  6. package/Models/DatabaseModels/ProjectOnCallCalendarFeed.ts +584 -0
  7. package/Models/DatabaseModels/StatusPageDomain.ts +43 -0
  8. package/Models/DatabaseModels/UserOnCallCalendarFeed.ts +546 -0
  9. package/Models/DatabaseModels/UserOnCallShiftReminder.ts +231 -0
  10. package/Models/DatabaseModels/UserOnCallShiftReminderLog.ts +331 -0
  11. package/Server/API/DashboardDomainAPI.ts +74 -0
  12. package/Server/API/MicrosoftTeamsAPI.ts +81 -180
  13. package/Server/API/OnCallCalendarAPI.ts +2194 -0
  14. package/Server/API/StatusPageDomainAPI.ts +74 -0
  15. package/Server/EnvironmentConfig.ts +138 -0
  16. package/Server/Infrastructure/OnCallCalendarFeedCache.ts +1050 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1790200000000-AllowNullMonitorNameOnMonitorTemplate.ts +43 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1790300000000-AddCertificateReissueRequestedAtToDomains.ts +40 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1790400000000-AddOnCallCalendarFeeds.ts +253 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  21. package/Server/Middleware/OnCallCalendarFeedRateLimit.ts +487 -0
  22. package/Server/Middleware/ProjectAuthorization.ts +6 -1
  23. package/Server/Services/DashboardDomainService.ts +131 -0
  24. package/Server/Services/Index.ts +12 -0
  25. package/Server/Services/LogPipelineProcessorService.ts +88 -0
  26. package/Server/Services/MonitorTemplateService.ts +70 -11
  27. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +32 -0
  28. package/Server/Services/OnCallDutyPolicyScheduleCalendarFeedService.ts +260 -0
  29. package/Server/Services/OnCallDutyPolicyScheduleLayerService.ts +70 -3
  30. package/Server/Services/OnCallDutyPolicyScheduleLayerUserService.ts +138 -3
  31. package/Server/Services/OnCallDutyPolicyScheduleService.ts +1465 -134
  32. package/Server/Services/OnCallDutyPolicyUserOverrideService.ts +167 -31
  33. package/Server/Services/ProjectOnCallCalendarFeedService.ts +192 -0
  34. package/Server/Services/StatusPageDomainService.ts +163 -3
  35. package/Server/Services/StatusPagePrivateUserSessionService.ts +197 -56
  36. package/Server/Services/TeamMemberService.ts +489 -1
  37. package/Server/Services/TeamService.ts +50 -0
  38. package/Server/Services/UserNotificationSettingService.ts +44 -1
  39. package/Server/Services/UserOnCallCalendarFeedService.ts +159 -0
  40. package/Server/Services/UserOnCallShiftReminderLogService.ts +151 -0
  41. package/Server/Services/UserOnCallShiftReminderService.ts +112 -0
  42. package/Server/Types/Domain.ts +17 -0
  43. package/Server/Utils/APIKey/AccessPermission.ts +24 -0
  44. package/Server/Utils/Greenlock/Greenlock.ts +156 -58
  45. package/Server/Utils/LogPipelineProcessorValidation.ts +112 -0
  46. package/Server/Utils/OnCall/CalendarFeedToken.ts +241 -0
  47. package/Server/Utils/OnCall/OnCallCalendarFeedRenderer.ts +1488 -0
  48. package/Server/Utils/OnCall/OnCallCalendarFeedUrls.ts +230 -0
  49. package/Server/Utils/OnCall/OnCallShiftChangeListeners.ts +227 -0
  50. package/Server/Utils/OnCall/OnCallShiftMaterializer.ts +1127 -0
  51. package/Server/Utils/OnCall/OnCallShiftReminderListener.ts +174 -0
  52. package/Server/Utils/OnCall/OnCallShiftReminderRunner.ts +2584 -0
  53. package/Server/Utils/Response.ts +134 -0
  54. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.ts +1094 -45
  55. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +153 -17
  56. package/Server/Utils/StartServer.ts +10 -0
  57. package/Server/Utils/Telemetry/AppMetrics.ts +51 -0
  58. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +23 -11
  59. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +0 -170
  60. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Authorization.ts +158 -0
  61. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +23 -11
  62. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +35 -13
  63. package/Tests/App/Dashboard/MonitorTemplateColumnAndFacet.test.tsx +505 -0
  64. package/Tests/App/Dashboard/OnCallCalendarFeedLinks.test.tsx +229 -0
  65. package/Tests/App/Dashboard/OnCallCalendarFeedPlanGate.test.tsx +489 -0
  66. package/Tests/App/Dashboard/OnCallCalendarFeedSideMenus.test.tsx +149 -0
  67. package/Tests/App/Dashboard/OnCallCalendarFeedUtil.test.ts +855 -0
  68. package/Tests/App/Dashboard/OnCallPersonalCalendarFeed.test.tsx +1209 -0
  69. package/Tests/App/Dashboard/OnCallSharedCalendarFeedCard.test.tsx +1019 -0
  70. package/Tests/App/Dashboard/OnCallShiftRemindersAndUpcomingShifts.test.tsx +655 -0
  71. package/Tests/App/Dashboard/UserSettingsSetupChecklistModel.test.ts +73 -0
  72. package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +106 -0
  73. package/Tests/App/StatusPage/StatusPageLoginCodeUtil.test.ts +84 -0
  74. package/Tests/App/StatusPage/StatusPageRedirectSafety.test.ts +119 -0
  75. package/Tests/Models/MonitorTemplateMonitorNameColumn.test.ts +258 -0
  76. package/Tests/Models/OnCallCalendarFeedModels.test.ts +642 -0
  77. package/Tests/Models/OnCallDutyPolicyScheduleCalendarFeed.test.ts +288 -0
  78. package/Tests/Models/OnCallDutyPolicyScheduleShiftConfigVersion.test.ts +88 -0
  79. package/Tests/Models/UserOnCallShiftReminderModels.test.ts +368 -0
  80. package/Tests/Server/API/CustomDomainReissueSslAPI.test.ts +469 -0
  81. package/Tests/Server/API/Helpers.ts +8 -0
  82. package/Tests/Server/API/MicrosoftTeamsBotMessagesEndpoint.test.ts +729 -0
  83. package/Tests/Server/API/MicrosoftTeamsBotTestEndpoint.test.ts +26 -0
  84. package/Tests/Server/API/MicrosoftTeamsLegacyWebhookRemoval.test.ts +402 -0
  85. package/Tests/Server/API/OnCallCalendarAPI.test.ts +4461 -0
  86. package/Tests/Server/EnvironmentConfigOnCallCalendarFeed.test.ts +357 -0
  87. package/Tests/Server/Infrastructure/OnCallCalendarFeedCache.test.ts +1589 -0
  88. package/Tests/Server/Infrastructure/Postgres/AddOnCallCalendarFeedsMigration.test.ts +369 -0
  89. package/Tests/Server/Middleware/OnCallCalendarFeedRateLimit.test.ts +1365 -0
  90. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -0
  91. package/Tests/Server/Services/AddCertificateReissueRequestedAtToDomainsMigration.test.ts +287 -0
  92. package/Tests/Server/Services/CustomDomainCertificateReissue.test.ts +477 -0
  93. package/Tests/Server/Services/FeedRetentionConsistency.test.ts +70 -0
  94. package/Tests/Server/Services/LogPipelineProcessorSaveValidation.test.ts +249 -0
  95. package/Tests/Server/Services/MonitorTemplateServiceBulkSync.test.ts +549 -0
  96. package/Tests/Server/Services/MonitorTemplateServiceNetworkDeviceSync.test.ts +16 -3
  97. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +57 -0
  98. package/Tests/Server/Services/OnCallCalendarFeedServices.test.ts +1103 -0
  99. package/Tests/Server/Services/OnCallDutyPolicyScheduleResolver.test.ts +1037 -0
  100. package/Tests/Server/Services/OnCallShiftConfigPropagation.test.ts +1270 -0
  101. package/Tests/Server/Services/SecurityEventLastErrorColumnWidth.test.ts +151 -15
  102. package/Tests/Server/Services/StatusPagePrivateUserSessionService.test.ts +587 -0
  103. package/Tests/Server/Services/TeamDeleteMemberCleanup.test.ts +156 -0
  104. package/Tests/Server/Services/TeamMemberOnCallCleanup.test.ts +755 -0
  105. package/Tests/Server/Services/UserNotificationSettingShiftReminderDefaults.test.ts +267 -0
  106. package/Tests/Server/Services/UserOnCallShiftReminderServices.test.ts +583 -0
  107. package/Tests/Server/Types/Database/Permissions/ApiKeyFileAccess.test.ts +286 -0
  108. package/Tests/Server/Types/Database/Permissions/MonitorTemplateColumnAccess.test.ts +328 -0
  109. package/Tests/Server/Types/Database/Permissions/OnCallCalendarFeedPermissions.test.ts +254 -0
  110. package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAndIsNull.test.ts +83 -0
  111. package/Tests/Server/Utils/AI/SRE/ConfidenceSignal.test.ts +377 -0
  112. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +16 -1
  113. package/Tests/Server/Utils/Greenlock/CertificateRenewalSchedule.test.ts +250 -0
  114. package/Tests/Server/Utils/LogPipelineProcessorValidation.test.ts +198 -0
  115. package/Tests/Server/Utils/OnCall/CalendarFeedToken.test.ts +467 -0
  116. package/Tests/Server/Utils/OnCall/OnCallCalendarFeedRenderer.test.ts +2142 -0
  117. package/Tests/Server/Utils/OnCall/OnCallCalendarFeedUrls.test.ts +278 -0
  118. package/Tests/Server/Utils/OnCall/OnCallResolverTestHarness.ts +440 -0
  119. package/Tests/Server/Utils/OnCall/OnCallShiftChangeListeners.test.ts +314 -0
  120. package/Tests/Server/Utils/OnCall/OnCallShiftMaterializer.test.ts +1502 -0
  121. package/Tests/Server/Utils/OnCall/OnCallShiftReminderListener.test.ts +491 -0
  122. package/Tests/Server/Utils/OnCall/OnCallShiftReminderRunner.test.ts +3088 -0
  123. package/Tests/Server/Utils/OnCall/OnCallShiftReminderTestHarness.ts +910 -0
  124. package/Tests/Server/Utils/ResponseSendCalendarResponse.test.ts +561 -0
  125. package/Tests/Server/Utils/SecurityEvent/ConnectorErrorMessage.test.ts +48 -9
  126. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsAuth.test.ts +726 -0
  127. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClient.test.ts +74 -11
  128. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsErrorHandling.test.ts +1107 -0
  129. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +20 -3
  130. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +51 -11
  131. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +1246 -0
  132. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsRequestContract.test.ts +961 -0
  133. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsResponseParsing.test.ts +653 -0
  134. package/Tests/Server/Utils/StartServerEncryptionSecretWarning.test.ts +64 -0
  135. package/Tests/Server/Utils/Telemetry/AppMetrics.test.ts +29 -0
  136. package/Tests/Server/Utils/Workspace/MicrosoftTeamsActionAuthorization.test.ts +880 -0
  137. package/Tests/Types/API/HTTPResponse.test.ts +175 -0
  138. package/Tests/Types/API/Route.test.ts +36 -4
  139. package/Tests/Types/Calendar/ICalendar.test.ts +488 -0
  140. package/Tests/Types/Database/DatabaseProperty.test.ts +171 -0
  141. package/Tests/Types/DateLocalShortDateTimeString.test.ts +518 -0
  142. package/Tests/Types/DateLocalTimeString.test.ts +259 -0
  143. package/Tests/Types/DateUserPrefers12HourFormat.test.ts +316 -0
  144. package/Tests/Types/NotificationSetting/NotificationSettingEventType.test.ts +53 -0
  145. package/Tests/Types/OnCallDutyPolicy/CalendarFeedTestFixtures.ts +310 -0
  146. package/Tests/Types/OnCallDutyPolicy/CalendarFeedWindow.test.ts +205 -0
  147. package/Tests/Types/OnCallDutyPolicy/LayerUtilLayerMetaAndIterationCap.test.ts +458 -0
  148. package/Tests/Types/OnCallDutyPolicy/MaterializedShift.test.ts +197 -0
  149. package/Tests/Types/OnCallDutyPolicy/OnCallCalendarFeedUtil.test.ts +1986 -0
  150. package/Tests/Types/OnCallDutyPolicy/ScheduleShiftUtilGroupKey.test.ts +678 -0
  151. package/Tests/Types/OnCallDutyPolicy/ShiftSeamUtil.test.ts +417 -0
  152. package/Tests/UI/Components/LogsHistogram.test.tsx +41 -2
  153. package/Tests/UI/Components/LogsViewerEmptyStateTimeRange.test.tsx +212 -0
  154. package/Tests/UI/Components/TelemetryChartClockFormat.test.tsx +359 -0
  155. package/Tests/UI/Components/TimeRangePickerClockFormat.test.tsx +422 -0
  156. package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +146 -8
  157. package/Tests/UI/MicrosoftTeams/MicrosoftTeamsMessagingEndpointGuidance.test.tsx +520 -0
  158. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
  159. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
  160. package/Tests/UI/Utils/Navigation.test.ts +82 -0
  161. package/Tests/Utils/Array.test.ts +100 -0
  162. package/Tests/Utils/CertificateReissue.test.ts +225 -0
  163. package/Tests/Utils/Grok/Grok.test.ts +492 -0
  164. package/Tests/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.test.ts +181 -13
  165. package/Types/API/Route.ts +20 -5
  166. package/Types/Calendar/ICalendar.ts +442 -0
  167. package/Types/Date.ts +143 -13
  168. package/Types/Email/EmailTemplateType.ts +2 -0
  169. package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
  170. package/Types/OnCallDutyPolicy/CalendarFeedWindow.ts +140 -0
  171. package/Types/OnCallDutyPolicy/Layer.ts +190 -35
  172. package/Types/OnCallDutyPolicy/MaterializedShift.ts +274 -0
  173. package/Types/OnCallDutyPolicy/OnCallCalendarFeedUtil.ts +1415 -0
  174. package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +159 -4
  175. package/Types/OnCallDutyPolicy/ShiftSeamUtil.ts +106 -0
  176. package/Types/Rum/SessionReplay.ts +62 -1
  177. package/UI/Components/Date/TimeRangePickerDropdown.tsx +9 -5
  178. package/UI/Components/LogsViewer/LogsViewer.tsx +12 -7
  179. package/UI/Components/LogsViewer/components/HistogramTooltip.tsx +18 -17
  180. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +21 -28
  181. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +2 -4
  182. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +2 -4
  183. package/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.tsx +17 -16
  184. package/UI/Utils/Navigation.ts +42 -0
  185. package/Utils/Array.ts +37 -0
  186. package/Utils/CertificateReissue.ts +128 -0
  187. package/Utils/Grok/Grok.ts +461 -0
  188. package/Utils/Grok/GrokPatterns.ts +118 -0
  189. package/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.ts +58 -6
  190. package/build/dist/Models/DatabaseModels/DashboardDomain.js +44 -0
  191. package/build/dist/Models/DatabaseModels/DashboardDomain.js.map +1 -1
  192. package/build/dist/Models/DatabaseModels/Index.js +11 -0
  193. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  194. package/build/dist/Models/DatabaseModels/MonitorTemplate.js +17 -4
  195. package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
  196. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +44 -0
  197. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  198. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js +699 -0
  199. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js.map +1 -0
  200. package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js +620 -0
  201. package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js.map +1 -0
  202. package/build/dist/Models/DatabaseModels/StatusPageDomain.js +44 -0
  203. package/build/dist/Models/DatabaseModels/StatusPageDomain.js.map +1 -1
  204. package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js +585 -0
  205. package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js.map +1 -0
  206. package/build/dist/Models/DatabaseModels/UserOnCallShiftReminder.js +247 -0
  207. package/build/dist/Models/DatabaseModels/UserOnCallShiftReminder.js.map +1 -0
  208. package/build/dist/Models/DatabaseModels/UserOnCallShiftReminderLog.js +355 -0
  209. package/build/dist/Models/DatabaseModels/UserOnCallShiftReminderLog.js.map +1 -0
  210. package/build/dist/Server/API/DashboardDomainAPI.js +43 -1
  211. package/build/dist/Server/API/DashboardDomainAPI.js.map +1 -1
  212. package/build/dist/Server/API/MicrosoftTeamsAPI.js +74 -118
  213. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  214. package/build/dist/Server/API/OnCallCalendarAPI.js +1371 -0
  215. package/build/dist/Server/API/OnCallCalendarAPI.js.map +1 -0
  216. package/build/dist/Server/API/StatusPageDomainAPI.js +43 -1
  217. package/build/dist/Server/API/StatusPageDomainAPI.js.map +1 -1
  218. package/build/dist/Server/EnvironmentConfig.js +102 -0
  219. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  220. package/build/dist/Server/Infrastructure/OnCallCalendarFeedCache.js +663 -0
  221. package/build/dist/Server/Infrastructure/OnCallCalendarFeedCache.js.map +1 -0
  222. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790200000000-AllowNullMonitorNameOnMonitorTemplate.js +34 -0
  223. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790200000000-AllowNullMonitorNameOnMonitorTemplate.js.map +1 -0
  224. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790300000000-AddCertificateReissueRequestedAtToDomains.js +28 -0
  225. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790300000000-AddCertificateReissueRequestedAtToDomains.js.map +1 -0
  226. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790400000000-AddOnCallCalendarFeeds.js +103 -0
  227. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790400000000-AddOnCallCalendarFeeds.js.map +1 -0
  228. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  230. package/build/dist/Server/Middleware/OnCallCalendarFeedRateLimit.js +342 -0
  231. package/build/dist/Server/Middleware/OnCallCalendarFeedRateLimit.js.map +1 -0
  232. package/build/dist/Server/Middleware/ProjectAuthorization.js +6 -1
  233. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  234. package/build/dist/Server/Services/DashboardDomainService.js +104 -0
  235. package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
  236. package/build/dist/Server/Services/Index.js +12 -0
  237. package/build/dist/Server/Services/Index.js.map +1 -1
  238. package/build/dist/Server/Services/LogPipelineProcessorService.js +65 -0
  239. package/build/dist/Server/Services/LogPipelineProcessorService.js.map +1 -1
  240. package/build/dist/Server/Services/MonitorTemplateService.js +57 -11
  241. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  242. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +20 -0
  243. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  244. package/build/dist/Server/Services/OnCallDutyPolicyScheduleCalendarFeedService.js +219 -0
  245. package/build/dist/Server/Services/OnCallDutyPolicyScheduleCalendarFeedService.js.map +1 -0
  246. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js +47 -3
  247. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js.map +1 -1
  248. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js +112 -3
  249. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js.map +1 -1
  250. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +955 -9
  251. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  252. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js +93 -6
  253. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js.map +1 -1
  254. package/build/dist/Server/Services/ProjectOnCallCalendarFeedService.js +157 -0
  255. package/build/dist/Server/Services/ProjectOnCallCalendarFeedService.js.map +1 -0
  256. package/build/dist/Server/Services/StatusPageDomainService.js +132 -3
  257. package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
  258. package/build/dist/Server/Services/StatusPagePrivateUserSessionService.js +112 -32
  259. package/build/dist/Server/Services/StatusPagePrivateUserSessionService.js.map +1 -1
  260. package/build/dist/Server/Services/TeamMemberService.js +396 -1
  261. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  262. package/build/dist/Server/Services/TeamService.js +43 -0
  263. package/build/dist/Server/Services/TeamService.js.map +1 -1
  264. package/build/dist/Server/Services/UserNotificationSettingService.js +26 -1
  265. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  266. package/build/dist/Server/Services/UserOnCallCalendarFeedService.js +140 -0
  267. package/build/dist/Server/Services/UserOnCallCalendarFeedService.js.map +1 -0
  268. package/build/dist/Server/Services/UserOnCallShiftReminderLogService.js +116 -0
  269. package/build/dist/Server/Services/UserOnCallShiftReminderLogService.js.map +1 -0
  270. package/build/dist/Server/Services/UserOnCallShiftReminderService.js +92 -0
  271. package/build/dist/Server/Services/UserOnCallShiftReminderService.js.map +1 -0
  272. package/build/dist/Server/Types/Domain.js +16 -0
  273. package/build/dist/Server/Types/Domain.js.map +1 -1
  274. package/build/dist/Server/Utils/APIKey/AccessPermission.js +24 -0
  275. package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
  276. package/build/dist/Server/Utils/Greenlock/Greenlock.js +110 -35
  277. package/build/dist/Server/Utils/Greenlock/Greenlock.js.map +1 -1
  278. package/build/dist/Server/Utils/LogPipelineProcessorValidation.js +77 -0
  279. package/build/dist/Server/Utils/LogPipelineProcessorValidation.js.map +1 -0
  280. package/build/dist/Server/Utils/OnCall/CalendarFeedToken.js +161 -0
  281. package/build/dist/Server/Utils/OnCall/CalendarFeedToken.js.map +1 -0
  282. package/build/dist/Server/Utils/OnCall/OnCallCalendarFeedRenderer.js +983 -0
  283. package/build/dist/Server/Utils/OnCall/OnCallCalendarFeedRenderer.js.map +1 -0
  284. package/build/dist/Server/Utils/OnCall/OnCallCalendarFeedUrls.js +155 -0
  285. package/build/dist/Server/Utils/OnCall/OnCallCalendarFeedUrls.js.map +1 -0
  286. package/build/dist/Server/Utils/OnCall/OnCallShiftChangeListeners.js +145 -0
  287. package/build/dist/Server/Utils/OnCall/OnCallShiftChangeListeners.js.map +1 -0
  288. package/build/dist/Server/Utils/OnCall/OnCallShiftMaterializer.js +752 -0
  289. package/build/dist/Server/Utils/OnCall/OnCallShiftMaterializer.js.map +1 -0
  290. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderListener.js +92 -0
  291. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderListener.js.map +1 -0
  292. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js +1786 -0
  293. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js.map +1 -0
  294. package/build/dist/Server/Utils/Response.js +97 -0
  295. package/build/dist/Server/Utils/Response.js.map +1 -1
  296. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js +777 -36
  297. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +1 -1
  298. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +108 -17
  299. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +1 -1
  300. package/build/dist/Server/Utils/StartServer.js +9 -1
  301. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  302. package/build/dist/Server/Utils/Telemetry/AppMetrics.js +41 -0
  303. package/build/dist/Server/Utils/Telemetry/AppMetrics.js.map +1 -1
  304. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +17 -6
  305. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
  306. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +0 -159
  307. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
  308. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Authorization.js +128 -0
  309. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Authorization.js.map +1 -0
  310. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +17 -6
  311. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  312. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +25 -13
  313. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  314. package/build/dist/Types/API/Route.js +16 -5
  315. package/build/dist/Types/API/Route.js.map +1 -1
  316. package/build/dist/Types/Calendar/ICalendar.js +290 -0
  317. package/build/dist/Types/Calendar/ICalendar.js.map +1 -0
  318. package/build/dist/Types/Date.js +115 -13
  319. package/build/dist/Types/Date.js.map +1 -1
  320. package/build/dist/Types/Email/EmailTemplateType.js +2 -0
  321. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  322. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
  323. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  324. package/build/dist/Types/OnCallDutyPolicy/CalendarFeedWindow.js +97 -0
  325. package/build/dist/Types/OnCallDutyPolicy/CalendarFeedWindow.js.map +1 -0
  326. package/build/dist/Types/OnCallDutyPolicy/Layer.js +113 -19
  327. package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
  328. package/build/dist/Types/OnCallDutyPolicy/MaterializedShift.js +134 -0
  329. package/build/dist/Types/OnCallDutyPolicy/MaterializedShift.js.map +1 -0
  330. package/build/dist/Types/OnCallDutyPolicy/OnCallCalendarFeedUtil.js +800 -0
  331. package/build/dist/Types/OnCallDutyPolicy/OnCallCalendarFeedUtil.js.map +1 -0
  332. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +97 -3
  333. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
  334. package/build/dist/Types/OnCallDutyPolicy/ShiftSeamUtil.js +77 -0
  335. package/build/dist/Types/OnCallDutyPolicy/ShiftSeamUtil.js.map +1 -0
  336. package/build/dist/Types/Rum/SessionReplay.js +38 -0
  337. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  338. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +9 -5
  339. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -1
  340. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +12 -7
  341. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  342. package/build/dist/UI/Components/LogsViewer/components/HistogramTooltip.js +15 -14
  343. package/build/dist/UI/Components/LogsViewer/components/HistogramTooltip.js.map +1 -1
  344. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +17 -22
  345. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  346. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +2 -4
  347. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  348. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +2 -4
  349. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  350. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.js +15 -14
  351. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.js.map +1 -1
  352. package/build/dist/UI/Utils/Navigation.js +30 -0
  353. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  354. package/build/dist/Utils/Array.js +25 -0
  355. package/build/dist/Utils/Array.js.map +1 -1
  356. package/build/dist/Utils/CertificateReissue.js +97 -0
  357. package/build/dist/Utils/CertificateReissue.js.map +1 -0
  358. package/build/dist/Utils/Grok/Grok.js +324 -0
  359. package/build/dist/Utils/Grok/Grok.js.map +1 -0
  360. package/build/dist/Utils/Grok/GrokPatterns.js +112 -0
  361. package/build/dist/Utils/Grok/GrokPatterns.js.map +1 -0
  362. package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js +63 -3
  363. package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js.map +1 -1
  364. package/package.json +1 -1
  365. package/UI/Utils/JsonWebToken.ts +0 -14
  366. package/build/dist/UI/Utils/JsonWebToken.js +0 -10
  367. package/build/dist/UI/Utils/JsonWebToken.js.map +0 -1
@@ -0,0 +1,159 @@
1
+ import CreateBy from "../Types/Database/CreateBy";
2
+ import UpdateBy from "../Types/Database/UpdateBy";
3
+ import { OnCreate, OnUpdate } from "../Types/Database/Hooks";
4
+ import DatabaseService from "./DatabaseService";
5
+ import CalendarFeedToken, {
6
+ CalendarFeedRotation,
7
+ MintedCalendarFeedToken,
8
+ } from "../Utils/OnCall/CalendarFeedToken";
9
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
10
+ import Model from "../../Models/DatabaseModels/UserOnCallCalendarFeed";
11
+ import BadDataException from "../../Types/Exception/BadDataException";
12
+ import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
13
+ import NotFoundException from "../../Types/Exception/NotFoundException";
14
+ import CalendarFeedWindow from "../../Types/OnCallDutyPolicy/CalendarFeedWindow";
15
+ import ObjectID from "../../Types/ObjectID";
16
+ import OneUptimeDate from "../../Types/Date";
17
+
18
+ /*
19
+ * The personal calendar feed row: one per (project, user).
20
+ *
21
+ * WHAT THE HOOKS GUARANTEE
22
+ *
23
+ * - Only root creates one. The table create list is already empty, but the
24
+ * hook says it out loud: the plaintext token is minted here or by the
25
+ * calendar API, never by a request body.
26
+ * - A created row always carries a consistent token set (see
27
+ * CalendarFeedToken.applyTokenColumnsOnCreate): there is no path to a row
28
+ * whose hash does not match its token.
29
+ * - pastDays / futureDays are clamped to the CalendarFeedWindow bounds on
30
+ * every write, so a feed can never be asked to render a year.
31
+ *
32
+ * Rotation lives here too (rotateTokenById) so the grace-hash bookkeeping is
33
+ * written once and the API, the member-leave cleanup and the tests share it.
34
+ * Cache purging is the caller's job - this service knows nothing about the
35
+ * feed cache.
36
+ */
37
+ export class Service extends DatabaseService<Model> {
38
+ public constructor() {
39
+ super(Model);
40
+ }
41
+
42
+ @CaptureSpan()
43
+ protected override async onBeforeCreate(
44
+ createBy: CreateBy<Model>,
45
+ ): Promise<OnCreate<Model>> {
46
+ if (!createBy.props.isRoot) {
47
+ throw new NotAuthorizedException(
48
+ "Calendar feeds are generated by the calendar API, not created directly.",
49
+ );
50
+ }
51
+
52
+ const projectId: ObjectID | undefined =
53
+ createBy.data.projectId || createBy.props.tenantId;
54
+
55
+ if (!projectId) {
56
+ throw new BadDataException("projectId is required");
57
+ }
58
+
59
+ if (!createBy.data.userId) {
60
+ throw new BadDataException("userId is required");
61
+ }
62
+
63
+ createBy.data.projectId = projectId;
64
+
65
+ // Root only reaches this line, so a pre-minted token may be trusted.
66
+ CalendarFeedToken.applyTokenColumnsOnCreate(createBy.data, {
67
+ trustSuppliedToken: true,
68
+ });
69
+
70
+ createBy.data.pastDays = CalendarFeedWindow.clampPastDays(
71
+ createBy.data.pastDays,
72
+ );
73
+ createBy.data.futureDays = CalendarFeedWindow.clampFutureDays(
74
+ createBy.data.futureDays,
75
+ );
76
+
77
+ return { createBy, carryForward: null };
78
+ }
79
+
80
+ @CaptureSpan()
81
+ protected override async onBeforeUpdate(
82
+ updateBy: UpdateBy<Model>,
83
+ ): Promise<OnUpdate<Model>> {
84
+ if (updateBy.data.pastDays !== undefined) {
85
+ updateBy.data.pastDays = CalendarFeedWindow.clampPastDays(
86
+ updateBy.data.pastDays,
87
+ );
88
+ }
89
+
90
+ if (updateBy.data.futureDays !== undefined) {
91
+ updateBy.data.futureDays = CalendarFeedWindow.clampFutureDays(
92
+ updateBy.data.futureDays,
93
+ );
94
+ }
95
+
96
+ return { updateBy, carryForward: null };
97
+ }
98
+
99
+ /**
100
+ * Create the feed row for a user in a project and hand the plaintext token
101
+ * back ONCE, so the caller can build the subscription URL without a
102
+ * decrypt round-trip. Root only; the caller is responsible for holding the
103
+ * per-(project, user) lock the API uses around mint-or-rotate.
104
+ */
105
+ @CaptureSpan()
106
+ public async createForUser(data: {
107
+ projectId: ObjectID;
108
+ userId: ObjectID;
109
+ }): Promise<{ feed: Model; minted: MintedCalendarFeedToken }> {
110
+ const minted: MintedCalendarFeedToken = CalendarFeedToken.mintSet();
111
+
112
+ const feed: Model = new Model();
113
+ feed.projectId = data.projectId;
114
+ feed.userId = data.userId;
115
+ feed.token = minted.token;
116
+ feed.rotatedAt = OneUptimeDate.getCurrentDate();
117
+
118
+ const created: Model = await this.create({
119
+ data: feed,
120
+ props: { isRoot: true },
121
+ });
122
+
123
+ return { feed: created, minted };
124
+ }
125
+
126
+ /**
127
+ * Rotate the token of an existing feed: mint a new one, move the current
128
+ * hash into the 30-day grace slot, stamp rotatedAt. Returns the new
129
+ * plaintext token ONCE. Root write; the caller purges caches.
130
+ */
131
+ @CaptureSpan()
132
+ public async rotateTokenById(data: {
133
+ id: ObjectID;
134
+ }): Promise<CalendarFeedRotation> {
135
+ const existing: Model | null = await this.findOneBy({
136
+ query: { _id: data.id },
137
+ select: { _id: true, tokenHash: true },
138
+ props: { isRoot: true, ignoreHooks: true },
139
+ });
140
+
141
+ if (!existing) {
142
+ throw new NotFoundException("Calendar feed not found.");
143
+ }
144
+
145
+ const rotation: CalendarFeedRotation = CalendarFeedToken.buildRotation({
146
+ currentTokenHash: existing.tokenHash,
147
+ });
148
+
149
+ await this.updateOneById({
150
+ id: data.id,
151
+ data: CalendarFeedToken.toRotationUpdateData(rotation),
152
+ props: { isRoot: true },
153
+ });
154
+
155
+ return rotation;
156
+ }
157
+ }
158
+
159
+ export default new Service();
@@ -0,0 +1,151 @@
1
+ import CreateBy from "../Types/Database/CreateBy";
2
+ import DeleteBy from "../Types/Database/DeleteBy";
3
+ import UpdateBy from "../Types/Database/UpdateBy";
4
+ import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
5
+ import DatabaseService from "./DatabaseService";
6
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
7
+ import Model, {
8
+ UserOnCallShiftReminderLogKind,
9
+ } from "../../Models/DatabaseModels/UserOnCallShiftReminderLog";
10
+ import BadDataException from "../../Types/Exception/BadDataException";
11
+ import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
12
+ import ObjectID from "../../Types/ObjectID";
13
+ import OneUptimeDate from "../../Types/Date";
14
+
15
+ const MILLISECONDS_PER_MINUTE: number = 60 * 1000;
16
+
17
+ const ALLOWED_KINDS: Set<string> = new Set<string>(
18
+ Object.values(UserOnCallShiftReminderLogKind),
19
+ );
20
+
21
+ /*
22
+ * The shift-reminder ledger. Root only, in every direction: a claim row is
23
+ * the thing that makes "send exactly once" true, so nothing outside the
24
+ * worker may insert, edit or remove one.
25
+ *
26
+ * The create hook normalises the idempotency key so two workers that compute
27
+ * the same shift a few milliseconds apart still collide on the unique index:
28
+ * shiftStartsAt is truncated to the minute here as well as by the worker
29
+ * (belt and braces - the seam normalisation upstream already makes starts
30
+ * minute-granular, this makes it a guarantee of the table rather than of one
31
+ * caller), and minutesBeforeShift defaults to 0 for change notices.
32
+ */
33
+ export class Service extends DatabaseService<Model> {
34
+ public constructor() {
35
+ super(Model);
36
+ }
37
+
38
+ @CaptureSpan()
39
+ protected override async onBeforeCreate(
40
+ createBy: CreateBy<Model>,
41
+ ): Promise<OnCreate<Model>> {
42
+ if (!createBy.props.isRoot) {
43
+ throw new NotAuthorizedException(
44
+ "Shift reminder logs are written by the reminder worker only.",
45
+ );
46
+ }
47
+
48
+ const projectId: ObjectID | undefined =
49
+ createBy.data.projectId || createBy.props.tenantId;
50
+
51
+ if (!projectId) {
52
+ throw new BadDataException("projectId is required");
53
+ }
54
+
55
+ if (!createBy.data.userId) {
56
+ throw new BadDataException("userId is required");
57
+ }
58
+
59
+ if (!createBy.data.onCallDutyPolicyScheduleId) {
60
+ throw new BadDataException("onCallDutyPolicyScheduleId is required");
61
+ }
62
+
63
+ if (!createBy.data.shiftStartsAt) {
64
+ throw new BadDataException("shiftStartsAt is required");
65
+ }
66
+
67
+ if (
68
+ !createBy.data.kind ||
69
+ !ALLOWED_KINDS.has(createBy.data.kind as string)
70
+ ) {
71
+ throw new BadDataException(
72
+ `kind must be one of: ${Object.values(UserOnCallShiftReminderLogKind).join(", ")}`,
73
+ );
74
+ }
75
+
76
+ createBy.data.projectId = projectId;
77
+
78
+ createBy.data.shiftStartsAt = Service.truncateToMinute(
79
+ OneUptimeDate.fromString(createBy.data.shiftStartsAt),
80
+ );
81
+
82
+ createBy.data.minutesBeforeShift = Service.validateMinutesBeforeShift(
83
+ createBy.data.minutesBeforeShift,
84
+ );
85
+
86
+ if (!createBy.data.claimedAt) {
87
+ createBy.data.claimedAt = OneUptimeDate.getCurrentDate();
88
+ }
89
+
90
+ return { createBy, carryForward: null };
91
+ }
92
+
93
+ @CaptureSpan()
94
+ protected override async onBeforeUpdate(
95
+ updateBy: UpdateBy<Model>,
96
+ ): Promise<OnUpdate<Model>> {
97
+ if (!updateBy.props.isRoot) {
98
+ throw new NotAuthorizedException(
99
+ "Shift reminder logs are written by the reminder worker only.",
100
+ );
101
+ }
102
+
103
+ return { updateBy, carryForward: null };
104
+ }
105
+
106
+ @CaptureSpan()
107
+ protected override async onBeforeDelete(
108
+ deleteBy: DeleteBy<Model>,
109
+ ): Promise<OnDelete<Model>> {
110
+ if (!deleteBy.props.isRoot) {
111
+ throw new NotAuthorizedException(
112
+ "Shift reminder logs are written by the reminder worker only.",
113
+ );
114
+ }
115
+
116
+ return { deleteBy, carryForward: null };
117
+ }
118
+
119
+ // Zero the seconds and milliseconds. Part of the idempotency key.
120
+ public static truncateToMinute(date: Date): Date {
121
+ return new Date(
122
+ Math.floor(date.getTime() / MILLISECONDS_PER_MINUTE) *
123
+ MILLISECONDS_PER_MINUTE,
124
+ );
125
+ }
126
+
127
+ /*
128
+ * 0 (a change notice) or a positive whole number of minutes. Missing means
129
+ * 0. Anything else is a caller bug, not a value to store.
130
+ */
131
+ public static validateMinutesBeforeShift(value: unknown): number {
132
+ if (value === undefined || value === null) {
133
+ return 0;
134
+ }
135
+
136
+ const parsed: number =
137
+ typeof value === "string" && value.trim() !== ""
138
+ ? Number(value)
139
+ : (value as number);
140
+
141
+ if (typeof parsed !== "number" || !Number.isInteger(parsed) || parsed < 0) {
142
+ throw new BadDataException(
143
+ "minutesBeforeShift must be a whole number of minutes, 0 or more.",
144
+ );
145
+ }
146
+
147
+ return parsed;
148
+ }
149
+ }
150
+
151
+ export default new Service();
@@ -0,0 +1,112 @@
1
+ import CreateBy from "../Types/Database/CreateBy";
2
+ import UpdateBy from "../Types/Database/UpdateBy";
3
+ import { OnCreate, OnUpdate } from "../Types/Database/Hooks";
4
+ import DatabaseService from "./DatabaseService";
5
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
6
+ import Model, {
7
+ MAX_MINUTES_BEFORE_SHIFT,
8
+ MIN_MINUTES_BEFORE_SHIFT,
9
+ } from "../../Models/DatabaseModels/UserOnCallShiftReminder";
10
+ import BadDataException from "../../Types/Exception/BadDataException";
11
+ import ObjectID from "../../Types/ObjectID";
12
+ import PositiveNumber from "../../Types/PositiveNumber";
13
+
14
+ /*
15
+ * "Remind me N minutes before my shift" rows.
16
+ *
17
+ * The hooks keep the table honest for the reminder worker: every row has an
18
+ * owner (defaulted to the session user when the client did not send one, so
19
+ * the settings page can post `{ minutesBeforeShift }` and nothing else), a
20
+ * project, and a lead time inside 15 minutes ... 2 weeks. A duplicate lead
21
+ * is answered with a message rather than a unique-violation 500.
22
+ */
23
+ export class Service extends DatabaseService<Model> {
24
+ public constructor() {
25
+ super(Model);
26
+ }
27
+
28
+ @CaptureSpan()
29
+ protected override async onBeforeCreate(
30
+ createBy: CreateBy<Model>,
31
+ ): Promise<OnCreate<Model>> {
32
+ const projectId: ObjectID | undefined =
33
+ createBy.data.projectId || createBy.props.tenantId;
34
+
35
+ if (!projectId) {
36
+ throw new BadDataException("projectId is required");
37
+ }
38
+
39
+ if (!createBy.data.userId && createBy.props.userId) {
40
+ createBy.data.userId = createBy.props.userId;
41
+ }
42
+
43
+ if (!createBy.data.userId) {
44
+ throw new BadDataException("userId is required");
45
+ }
46
+
47
+ createBy.data.projectId = projectId;
48
+
49
+ createBy.data.minutesBeforeShift = Service.validateMinutesBeforeShift(
50
+ createBy.data.minutesBeforeShift,
51
+ );
52
+
53
+ const duplicates: PositiveNumber = await this.countBy({
54
+ query: {
55
+ projectId: projectId,
56
+ userId: createBy.data.userId,
57
+ minutesBeforeShift: createBy.data.minutesBeforeShift,
58
+ },
59
+ props: {
60
+ isRoot: true,
61
+ },
62
+ });
63
+
64
+ if (duplicates.toNumber() > 0) {
65
+ throw new BadDataException(
66
+ `You already have a reminder ${createBy.data.minutesBeforeShift} minutes before your shifts.`,
67
+ );
68
+ }
69
+
70
+ return { createBy, carryForward: null };
71
+ }
72
+
73
+ @CaptureSpan()
74
+ protected override async onBeforeUpdate(
75
+ updateBy: UpdateBy<Model>,
76
+ ): Promise<OnUpdate<Model>> {
77
+ if (updateBy.data.minutesBeforeShift !== undefined) {
78
+ updateBy.data.minutesBeforeShift = Service.validateMinutesBeforeShift(
79
+ updateBy.data.minutesBeforeShift,
80
+ );
81
+ }
82
+
83
+ return { updateBy, carryForward: null };
84
+ }
85
+
86
+ /*
87
+ * A whole number of minutes between MIN_MINUTES_BEFORE_SHIFT and
88
+ * MAX_MINUTES_BEFORE_SHIFT. Numeric strings are accepted (a form may post
89
+ * one); missing, fractional, negative or out-of-range values are a 400.
90
+ */
91
+ public static validateMinutesBeforeShift(value: unknown): number {
92
+ const parsed: number =
93
+ typeof value === "string" && value.trim() !== ""
94
+ ? Number(value)
95
+ : (value as number);
96
+
97
+ if (
98
+ typeof parsed !== "number" ||
99
+ !Number.isInteger(parsed) ||
100
+ parsed < MIN_MINUTES_BEFORE_SHIFT ||
101
+ parsed > MAX_MINUTES_BEFORE_SHIFT
102
+ ) {
103
+ throw new BadDataException(
104
+ `Reminder lead time must be a whole number of minutes between ${MIN_MINUTES_BEFORE_SHIFT} and ${MAX_MINUTES_BEFORE_SHIFT} (two weeks).`,
105
+ );
106
+ }
107
+
108
+ return parsed;
109
+ }
110
+ }
111
+
112
+ export default new Service();
@@ -11,6 +11,13 @@ import URL from "../../Types/API/URL";
11
11
  import API from "../../Utils/API";
12
12
  import DataSourceEgressGuard from "../Utils/DataSource/EgressGuard";
13
13
 
14
+ /*
15
+ * A status page that is up answers the verification path well inside this.
16
+ * It is a ceiling on how long one unreachable domain may hold up the rest of a
17
+ * certificate run, not a latency target.
18
+ */
19
+ export const DOMAIN_VERIFICATION_TIMEOUT_IN_MS: number = 10000;
20
+
14
21
  export default class Domain extends DomainCommon {
15
22
  /*
16
23
  * GET a domain-verification URL built from a tenant-supplied domain.
@@ -26,6 +33,15 @@ export default class Domain extends DomainCommon {
26
33
  *
27
34
  * Private ranges stay reachable on self-hosted installs, where a status page
28
35
  * domain legitimately resolves inside the corporate network.
36
+ *
37
+ * The call is bounded. A customer domain that has been pointed at an address
38
+ * which silently drops packets - a decommissioned load balancer, a firewall
39
+ * that blackholes instead of refusing - never answers and never resets, so an
40
+ * unbounded request sits until the kernel gives up on the TCP connect, which
41
+ * is a little over two minutes on Linux. The certificate crons walk every
42
+ * status page domain in turn, so each such domain would burn that timeout out
43
+ * of the run's budget and push the domains behind it into the next run - the
44
+ * renewals that matter get starved by the domains that will never answer.
29
45
  */
30
46
  @CaptureSpan()
31
47
  public static async getForDomainVerification(data: {
@@ -41,6 +57,7 @@ export default class Domain extends DomainCommon {
41
57
  url: URL.fromString(data.url),
42
58
  options: {
43
59
  doNotFollowRedirects: true,
60
+ timeout: DOMAIN_VERIFICATION_TIMEOUT_IN_MS,
44
61
  httpAgent,
45
62
  httpsAgent,
46
63
  },
@@ -10,6 +10,28 @@ import ApiKeyPermissionService, {
10
10
  import CaptureSpan from "../Telemetry/CaptureSpan";
11
11
  import UserPermissionUtil from "../UserPermission/UserPermission";
12
12
 
13
+ /*
14
+ * Permission.AuthenticatedRequest is a marker, not a capability. It says "some
15
+ * authenticated principal made this call" - its own definition names API keys
16
+ * first - and unlike every other entry in these lists it has no PermissionProps,
17
+ * so it never appears in the admin picker and nobody can grant or revoke it per
18
+ * key. File and FileModel are the only models that name it, which is what bounds
19
+ * what including it here can widen.
20
+ *
21
+ * It is in the list because of TenantPermission.isAccessGrantedOnlyByCurrentUser.
22
+ * That predicate asks whether the ONLY thing letting a caller through a model's
23
+ * gate is the auto-granted CurrentUser - i.e. whether they are here as nothing
24
+ * more than some logged-in user - and when it says yes the caller is held to
25
+ * rows they own, which an API key can never satisfy because it has no userId.
26
+ * Without AuthenticatedRequest an API key intersects File's create list down to
27
+ * CurrentUser alone and answers yes to that question, which is simply the wrong
28
+ * description of a key: it is not a user acting on their own rows.
29
+ *
30
+ * On File as it stands today the wrong answer is harmless - File declares no
31
+ * user column, so the ownership branch returns before it can bite. The grant is
32
+ * here so that stays a fact about File's schema rather than the only thing
33
+ * holding API-key file access up.
34
+ */
13
35
  export default class APIKeyAccessPermission {
14
36
  @CaptureSpan()
15
37
  public static async getDefaultApiGlobalPermission(
@@ -21,6 +43,7 @@ export default class APIKeyAccessPermission {
21
43
  Permission.Public,
22
44
  Permission.User,
23
45
  Permission.CurrentUser,
46
+ Permission.AuthenticatedRequest,
24
47
  ],
25
48
  _type: "UserGlobalAccessPermission",
26
49
  };
@@ -36,6 +59,7 @@ export default class APIKeyAccessPermission {
36
59
  Permission.Public,
37
60
  Permission.User,
38
61
  Permission.CurrentUser,
62
+ Permission.AuthenticatedRequest,
39
63
  Permission.ProjectOwner,
40
64
  ],
41
65
  _type: "UserGlobalAccessPermission",