@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,259 @@
1
+ /** @timezone America/Los_Angeles */
2
+ /**
3
+ * The clock reading behind every timestamp on the Logs / Traces / Metrics
4
+ * explorers - histogram x-axis ticks, histogram tooltips, span rows.
5
+ *
6
+ * Those sites used to call `date.toLocaleTimeString([], { hour12: false })`
7
+ * directly, which pinned them to a 24-hour clock and to the zone the browser
8
+ * process happens to run in. So a user whose computer keeps an AM/PM clock
9
+ * read "14:30" off a chart, and a user who had set a timezone in User
10
+ * Settings read a chart that disagreed with the log rows underneath it - in
11
+ * one Logs explorer the table's Time column and the histogram directly above
12
+ * it were formatted by two different rules.
13
+ *
14
+ * The docblock above pins the *browser* zone to Los Angeles and every case
15
+ * below configures a different zone, so a helper that quietly fell back to the
16
+ * process zone fails rather than passing by coincidence.
17
+ */
18
+ import OneUptimeDate from "../../Types/Date";
19
+ import Timezone from "../../Types/Timezone";
20
+ import { afterEach, describe, expect, it, jest } from "@jest/globals";
21
+
22
+ const UTC: Timezone = Timezone.UTC;
23
+ const NEW_YORK: Timezone = Timezone.AmericaNew_York;
24
+ const KOLKATA: Timezone = Timezone.AsiaKolkata;
25
+
26
+ /** 14:30 UTC - an afternoon, so a 12-hour clock has real work to do. */
27
+ const AFTERNOON: Date = new Date("2024-03-01T14:30:45.000Z");
28
+
29
+ type Options = {
30
+ includeMinutes?: boolean;
31
+ includeSeconds?: boolean;
32
+ use12HourFormat?: boolean | undefined;
33
+ };
34
+
35
+ function format(date: Date, options?: Options): string {
36
+ return OneUptimeDate.getLocalTimeString(date, options);
37
+ }
38
+
39
+ afterEach(() => {
40
+ // Never leak a pinned zone or a mocked preference into the rest of the suite.
41
+ OneUptimeDate.setUserTimezone(null);
42
+ jest.restoreAllMocks();
43
+ });
44
+
45
+ describe("OneUptimeDate.getLocalTimeString", () => {
46
+ /*
47
+ * The chart x-axes in UI/Components/Charts/Utils/XAxis.ts label ticks with
48
+ * this helper and are laid out for the fixed width of a 24-hour reading.
49
+ * They pass no preference, so the default has to stay where it was - these
50
+ * two cases are what makes the new option opt-in rather than a behaviour
51
+ * change for all nine of its existing callers.
52
+ */
53
+ describe("with no preference passed", () => {
54
+ it("keeps the 24-hour reading it has always produced", () => {
55
+ OneUptimeDate.setUserTimezone(UTC);
56
+
57
+ expect(format(AFTERNOON)).toBe("14:30");
58
+ });
59
+
60
+ it("does not consult the machine's clock preference at all", () => {
61
+ OneUptimeDate.setUserTimezone(UTC);
62
+
63
+ jest.spyOn(OneUptimeDate, "getUserPrefers12HourFormat");
64
+
65
+ format(AFTERNOON);
66
+
67
+ expect(OneUptimeDate.getUserPrefers12HourFormat).not.toHaveBeenCalled();
68
+ });
69
+
70
+ it("zero-pads the hour so ticks stay the same width", () => {
71
+ OneUptimeDate.setUserTimezone(UTC);
72
+
73
+ expect(format(new Date("2024-03-01T09:05:00.000Z"))).toBe("09:05");
74
+ expect(format(new Date("2024-03-01T00:00:00.000Z"))).toBe("00:00");
75
+ });
76
+
77
+ it("appends seconds only when asked", () => {
78
+ OneUptimeDate.setUserTimezone(UTC);
79
+
80
+ expect(format(AFTERNOON, { includeSeconds: true })).toBe("14:30:45");
81
+ });
82
+
83
+ it("returns the bare hour when minutes are turned off", () => {
84
+ OneUptimeDate.setUserTimezone(UTC);
85
+
86
+ expect(format(AFTERNOON, { includeMinutes: false })).toBe("14");
87
+ });
88
+ });
89
+
90
+ describe("on a 12-hour clock", () => {
91
+ it("marks an afternoon time PM", () => {
92
+ OneUptimeDate.setUserTimezone(UTC);
93
+
94
+ expect(format(AFTERNOON, { use12HourFormat: true })).toBe("2:30 PM");
95
+ });
96
+
97
+ it("marks a morning time AM", () => {
98
+ OneUptimeDate.setUserTimezone(UTC);
99
+
100
+ expect(
101
+ format(new Date("2024-03-01T09:05:00.000Z"), {
102
+ use12HourFormat: true,
103
+ }),
104
+ ).toBe("9:05 AM");
105
+ });
106
+
107
+ // The two readings a naive `hours % 12` gets wrong.
108
+ it("writes midnight as 12 AM rather than 0 AM", () => {
109
+ OneUptimeDate.setUserTimezone(UTC);
110
+
111
+ expect(
112
+ format(new Date("2024-03-01T00:00:00.000Z"), {
113
+ use12HourFormat: true,
114
+ }),
115
+ ).toBe("12:00 AM");
116
+ });
117
+
118
+ it("writes noon as 12 PM rather than 0 PM", () => {
119
+ OneUptimeDate.setUserTimezone(UTC);
120
+
121
+ expect(
122
+ format(new Date("2024-03-01T12:00:00.000Z"), {
123
+ use12HourFormat: true,
124
+ }),
125
+ ).toBe("12:00 PM");
126
+ });
127
+
128
+ it("keeps the marker after the seconds", () => {
129
+ OneUptimeDate.setUserTimezone(UTC);
130
+
131
+ expect(
132
+ format(AFTERNOON, { use12HourFormat: true, includeSeconds: true }),
133
+ ).toBe("2:30:45 PM");
134
+ });
135
+
136
+ it("keeps the marker on a bare hour", () => {
137
+ OneUptimeDate.setUserTimezone(UTC);
138
+
139
+ expect(
140
+ format(AFTERNOON, { use12HourFormat: true, includeMinutes: false }),
141
+ ).toBe("2 PM");
142
+ });
143
+ });
144
+
145
+ /*
146
+ * The browser here is in Los Angeles (see the docblock). None of the
147
+ * readings below are the Los Angeles ones, which is the point.
148
+ */
149
+ describe("reading the configured timezone rather than the browser's", () => {
150
+ it("shifts a whole-hour offset", () => {
151
+ OneUptimeDate.setUserTimezone(NEW_YORK);
152
+
153
+ expect(format(AFTERNOON)).toBe("09:30");
154
+ expect(format(AFTERNOON, { use12HourFormat: true })).toBe("9:30 AM");
155
+ });
156
+
157
+ it("shifts a half-hour offset", () => {
158
+ OneUptimeDate.setUserTimezone(KOLKATA);
159
+
160
+ expect(format(AFTERNOON)).toBe("20:00");
161
+ expect(format(AFTERNOON, { use12HourFormat: true })).toBe("8:00 PM");
162
+ });
163
+
164
+ it("crosses the date line into the next day", () => {
165
+ OneUptimeDate.setUserTimezone(KOLKATA);
166
+
167
+ // 23:00 UTC is already 04:30 the following morning in Kolkata.
168
+ expect(format(new Date("2024-03-01T23:00:00.000Z"))).toBe("04:30");
169
+ });
170
+
171
+ it("falls back to the browser zone when nothing is configured", () => {
172
+ OneUptimeDate.setUserTimezone(null);
173
+
174
+ // 14:30 UTC is 06:30 in Los Angeles on a March morning (PST, UTC-8).
175
+ expect(format(AFTERNOON)).toBe("06:30");
176
+ });
177
+ });
178
+ });
179
+
180
+ /*
181
+ * "Is this bucket today?" is what the histogram tooltips ask before deciding
182
+ * whether a timestamp needs its date spelled out. They used to ask it with
183
+ * `date.toDateString() === now.toDateString()`, which compares calendar days
184
+ * in the browser's zone - so within a few hours of midnight in the configured
185
+ * zone the date got dropped from buckets that needed it and added to buckets
186
+ * that did not.
187
+ */
188
+ describe("OneUptimeDate.areOnTheSameLocalDay", () => {
189
+ const BEFORE_MIDNIGHT_IN_KOLKATA: Date = new Date("2024-03-01T18:00:00.000Z");
190
+ const AFTER_MIDNIGHT_IN_KOLKATA: Date = new Date("2024-03-01T19:00:00.000Z");
191
+
192
+ it("separates two instants that straddle midnight in the configured zone", () => {
193
+ OneUptimeDate.setUserTimezone(KOLKATA);
194
+
195
+ /*
196
+ * 23:30 and 00:30 in Kolkata - two different days there, one hour apart.
197
+ * Both are still the same Friday morning in Los Angeles, which is exactly
198
+ * the disagreement the browser-zone comparison could not see.
199
+ */
200
+ expect(
201
+ OneUptimeDate.areOnTheSameLocalDay(
202
+ BEFORE_MIDNIGHT_IN_KOLKATA,
203
+ AFTER_MIDNIGHT_IN_KOLKATA,
204
+ ),
205
+ ).toBe(false);
206
+
207
+ expect(
208
+ OneUptimeDate.areOnTheSameDay(
209
+ BEFORE_MIDNIGHT_IN_KOLKATA,
210
+ AFTER_MIDNIGHT_IN_KOLKATA,
211
+ ),
212
+ ).toBe(true);
213
+ });
214
+
215
+ it("joins two instants the browser's zone splits across midnight", () => {
216
+ OneUptimeDate.setUserTimezone(KOLKATA);
217
+
218
+ // 07:30 and 21:30 on the same Kolkata day; Feb 29 and Mar 1 in Los Angeles.
219
+ const morning: Date = new Date("2024-03-01T02:00:00.000Z");
220
+ const evening: Date = new Date("2024-03-01T16:00:00.000Z");
221
+
222
+ expect(OneUptimeDate.areOnTheSameLocalDay(morning, evening)).toBe(true);
223
+ expect(OneUptimeDate.areOnTheSameDay(morning, evening)).toBe(false);
224
+ });
225
+
226
+ it("accepts the string form the histogram buckets arrive as", () => {
227
+ OneUptimeDate.setUserTimezone(UTC);
228
+
229
+ expect(
230
+ OneUptimeDate.areOnTheSameLocalDay(
231
+ "2024-03-01T00:30:00.000Z",
232
+ "2024-03-01T23:30:00.000Z",
233
+ ),
234
+ ).toBe(true);
235
+ });
236
+
237
+ it("falls back to the browser zone when nothing is configured", () => {
238
+ OneUptimeDate.setUserTimezone(null);
239
+
240
+ /*
241
+ * 16:00 and 20:00 UTC are 08:00 and 12:00 the same Los Angeles day, but
242
+ * two different UTC-relative readings - the browser's zone is the one
243
+ * that gets to answer when the user has configured none.
244
+ */
245
+ expect(
246
+ OneUptimeDate.areOnTheSameLocalDay(
247
+ new Date("2024-03-01T16:00:00.000Z"),
248
+ new Date("2024-03-01T20:00:00.000Z"),
249
+ ),
250
+ ).toBe(true);
251
+
252
+ expect(
253
+ OneUptimeDate.areOnTheSameLocalDay(
254
+ new Date("2024-03-01T02:00:00.000Z"),
255
+ new Date("2024-03-01T16:00:00.000Z"),
256
+ ),
257
+ ).toBe(false);
258
+ });
259
+ });
@@ -0,0 +1,316 @@
1
+ /**
2
+ * How OneUptime decides whether to write times on a 12- or a 24-hour clock.
3
+ *
4
+ * The answer has to come from the machine the person is sitting at: a browser
5
+ * resolves its default locale against the operating system's own clock setting,
6
+ * so toggling macOS's "24-Hour Time" (or the Windows/Linux equivalent) is meant
7
+ * to flip every time in the product.
8
+ *
9
+ * The bug these lock in: the check used to format a time and look for the
10
+ * letters "am"/"pm" in it. That is only how Latin-script locales mark the day
11
+ * period - ko-KR writes 오후, ar-EG writes م - so 12-hour machines in those
12
+ * locales were misread as 24-hour and got 24-hour times back. Intl reports the
13
+ * hour cycle directly, so it is asked first and the string probe is kept only
14
+ * as a fallback for an engine without a usable Intl.
15
+ */
16
+ import OneUptimeDate from "../../Types/Date";
17
+ import Timezone from "../../Types/Timezone";
18
+ import { afterEach, describe, expect, it, jest } from "@jest/globals";
19
+
20
+ type ResolvedOptionsStub = {
21
+ hour12?: boolean | undefined;
22
+ hourCycle?: string | undefined;
23
+ };
24
+
25
+ /*
26
+ * Stand in for the browser's resolved locale. `locales` records what the probe
27
+ * asked for so a test can assert it requested an hour at all - Intl only
28
+ * reports `hour12` when the format includes one, so a probe that forgot to ask
29
+ * would silently fall through to the string check on every engine.
30
+ */
31
+ type IntlProbeCall = {
32
+ locales: Intl.LocalesArgument;
33
+ options: Intl.DateTimeFormatOptions | undefined;
34
+ };
35
+
36
+ const probeCalls: Array<IntlProbeCall> = [];
37
+
38
+ type StubIntlFunction = (resolved: ResolvedOptionsStub | (() => never)) => void;
39
+
40
+ const stubIntl: StubIntlFunction = (
41
+ resolved: ResolvedOptionsStub | (() => never),
42
+ ): void => {
43
+ jest
44
+ .spyOn(Intl, "DateTimeFormat")
45
+ .mockImplementation(
46
+ (
47
+ locales?: Intl.LocalesArgument,
48
+ options?: Intl.DateTimeFormatOptions,
49
+ ) => {
50
+ probeCalls.push({ locales: locales, options: options });
51
+
52
+ if (typeof resolved === "function") {
53
+ resolved();
54
+ }
55
+
56
+ return {
57
+ resolvedOptions: () => {
58
+ return resolved as Intl.ResolvedDateTimeFormatOptions;
59
+ },
60
+ } as unknown as Intl.DateTimeFormat;
61
+ },
62
+ );
63
+ };
64
+
65
+ type StubFormattedTimeFunction = (formatted: string) => void;
66
+
67
+ const stubFormattedTime: StubFormattedTimeFunction = (
68
+ formatted: string,
69
+ ): void => {
70
+ jest.spyOn(Date.prototype, "toLocaleTimeString").mockImplementation(() => {
71
+ return formatted;
72
+ });
73
+ };
74
+
75
+ /*
76
+ * Delegate to the real Intl but pin the locale, so a case can assert what a
77
+ * machine actually configured to that locale reports rather than a hand-made
78
+ * stub of it.
79
+ */
80
+ type StubIntlWithLocaleFunction = (locale: string) => void;
81
+
82
+ const stubIntlWithLocale: StubIntlWithLocaleFunction = (
83
+ locale: string,
84
+ ): void => {
85
+ const realDateTimeFormat: typeof Intl.DateTimeFormat = Intl.DateTimeFormat;
86
+
87
+ jest
88
+ .spyOn(Intl, "DateTimeFormat")
89
+ .mockImplementation(
90
+ (
91
+ _locales?: Intl.LocalesArgument,
92
+ options?: Intl.DateTimeFormatOptions,
93
+ ) => {
94
+ return new realDateTimeFormat(locale, options);
95
+ },
96
+ );
97
+
98
+ /*
99
+ * Hold the legacy string probe to a bare 24-hour reading. Without this the
100
+ * fallback still sees the HOST's locale, so on a US runner the old am/pm
101
+ * substring check would answer "12-hour" by luck and the cases below would
102
+ * pass against the very implementation they exist to rule out.
103
+ */
104
+ stubFormattedTime("14:30:00");
105
+ };
106
+
107
+ describe("OneUptimeDate.getUserPrefers12HourFormat", () => {
108
+ afterEach(() => {
109
+ probeCalls.length = 0;
110
+ jest.restoreAllMocks();
111
+ OneUptimeDate.setUserTimezone(null);
112
+ });
113
+
114
+ describe("reading the machine's clock setting from Intl", () => {
115
+ it("reports a 12-hour machine as 12-hour", () => {
116
+ stubIntl({ hour12: true, hourCycle: "h12" });
117
+
118
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(true);
119
+ });
120
+
121
+ it("reports a 24-hour machine as 24-hour", () => {
122
+ stubIntl({ hour12: false, hourCycle: "h23" });
123
+
124
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(false);
125
+ });
126
+
127
+ it("asks for an hour, without which Intl reports no clock at all", () => {
128
+ stubIntl({ hour12: true });
129
+
130
+ OneUptimeDate.getUserPrefers12HourFormat();
131
+
132
+ expect(probeCalls).toHaveLength(1);
133
+ expect(probeCalls[0]?.options?.hour).toBeDefined();
134
+ });
135
+
136
+ it("asks for the machine's own locale rather than pinning one", () => {
137
+ stubIntl({ hour12: true });
138
+
139
+ OneUptimeDate.getUserPrefers12HourFormat();
140
+
141
+ /*
142
+ * Assert the probe ran before reading what it asked for - without this,
143
+ * an implementation that never called Intl would satisfy the line below
144
+ * on an empty array.
145
+ */
146
+ expect(probeCalls).toHaveLength(1);
147
+ // `undefined` is what makes Intl resolve the browser's default locale.
148
+ expect(probeCalls[0]?.locales).toBeUndefined();
149
+ });
150
+ });
151
+
152
+ describe("engines that report the cycle but not the boolean", () => {
153
+ it("treats h12 as a 12-hour clock", () => {
154
+ stubIntl({ hourCycle: "h12" });
155
+
156
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(true);
157
+ });
158
+
159
+ it("treats h11 as a 12-hour clock", () => {
160
+ stubIntl({ hourCycle: "h11" });
161
+
162
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(true);
163
+ });
164
+
165
+ it("treats h23 as a 24-hour clock", () => {
166
+ stubIntl({ hourCycle: "h23" });
167
+
168
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(false);
169
+ });
170
+
171
+ it("treats h24 as a 24-hour clock", () => {
172
+ stubIntl({ hourCycle: "h24" });
173
+
174
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(false);
175
+ });
176
+
177
+ it("prefers the boolean when both are reported and they disagree", () => {
178
+ /*
179
+ * hour12 is the value the spec says to honour; hourCycle is only read
180
+ * because older engines omit hour12 entirely.
181
+ */
182
+ stubIntl({ hour12: false, hourCycle: "h12" });
183
+
184
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(false);
185
+ });
186
+ });
187
+
188
+ describe("real locales", () => {
189
+ it("reads en-US as a 12-hour machine", () => {
190
+ stubIntlWithLocale("en-US");
191
+
192
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(true);
193
+ });
194
+
195
+ it("reads en-GB as a 24-hour machine", () => {
196
+ stubIntlWithLocale("en-GB");
197
+
198
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(false);
199
+ });
200
+
201
+ it("reads de-DE as a 24-hour machine", () => {
202
+ stubIntlWithLocale("de-DE");
203
+
204
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(false);
205
+ });
206
+
207
+ it("honours an explicit 24-hour override on a 12-hour locale", () => {
208
+ // What a US machine with "24-Hour Time" switched on resolves to.
209
+ stubIntlWithLocale("en-US-u-hc-h23");
210
+
211
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(false);
212
+ });
213
+
214
+ it("honours an explicit 12-hour override on a 24-hour locale", () => {
215
+ stubIntlWithLocale("de-DE-u-hc-h12");
216
+
217
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(true);
218
+ });
219
+
220
+ it("reads ko-KR as a 12-hour machine even though it writes 오후, not PM", () => {
221
+ /*
222
+ * The regression this whole change exists for: the old string probe saw
223
+ * "오후 2:30:00", found no "am"/"pm", and told a Korean user on a
224
+ * 12-hour machine they were on a 24-hour one.
225
+ */
226
+ stubIntlWithLocale("ko-KR");
227
+
228
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(true);
229
+ });
230
+
231
+ it("reads ar-EG as a 12-hour machine even though it writes م, not PM", () => {
232
+ stubIntlWithLocale("ar-EG");
233
+
234
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(true);
235
+ });
236
+ });
237
+
238
+ describe("falling back when Intl cannot answer", () => {
239
+ it("reads a Latin AM/PM out of a formatted time when Intl throws", () => {
240
+ stubIntl(() => {
241
+ throw new Error("Intl unavailable");
242
+ });
243
+ stubFormattedTime("2:30:00 PM");
244
+
245
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(true);
246
+ });
247
+
248
+ it("reads a bare 24-hour time out of a formatted time when Intl throws", () => {
249
+ stubIntl(() => {
250
+ throw new Error("Intl unavailable");
251
+ });
252
+ stubFormattedTime("14:30:00");
253
+
254
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(false);
255
+ });
256
+
257
+ it("falls back when Intl answers with neither a boolean nor a cycle", () => {
258
+ stubIntl({});
259
+ stubFormattedTime("2:30:00 AM");
260
+
261
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(true);
262
+ });
263
+
264
+ it("matches a lowercase day period", () => {
265
+ stubIntl({});
266
+ stubFormattedTime("2:30:00 pm");
267
+
268
+ expect(OneUptimeDate.getUserPrefers12HourFormat()).toBe(true);
269
+ });
270
+
271
+ it("does not throw when Intl is broken and the time has no day period", () => {
272
+ stubIntl(() => {
273
+ throw new Error("Intl unavailable");
274
+ });
275
+ stubFormattedTime("14:30:00");
276
+
277
+ expect(() => {
278
+ return OneUptimeDate.getUserPrefers12HourFormat();
279
+ }).not.toThrow();
280
+ });
281
+ });
282
+
283
+ describe("as a decision the rest of the product reads", () => {
284
+ it("drives the clock of the time range picker's custom label", () => {
285
+ /*
286
+ * The user-visible consequence, end to end: the same instant is written
287
+ * two different ways purely on the strength of this one answer.
288
+ */
289
+ /*
290
+ * Pin the zone: without it this reads 2:30 PM on a UTC runner and 6:30 AM
291
+ * on a Los Angeles one, and the assertion is about the clock, not the
292
+ * zone.
293
+ */
294
+ OneUptimeDate.setUserTimezone(Timezone.UTC);
295
+
296
+ stubIntlWithLocale("en-US");
297
+ const on12HourMachine: string =
298
+ OneUptimeDate.getDateAsLocalShortDateTimeString(
299
+ new Date("2024-03-01T14:30:00.000Z"),
300
+ { use12HourFormat: OneUptimeDate.getUserPrefers12HourFormat() },
301
+ );
302
+
303
+ jest.restoreAllMocks();
304
+
305
+ stubIntlWithLocale("en-GB");
306
+ const on24HourMachine: string =
307
+ OneUptimeDate.getDateAsLocalShortDateTimeString(
308
+ new Date("2024-03-01T14:30:00.000Z"),
309
+ { use12HourFormat: OneUptimeDate.getUserPrefers12HourFormat() },
310
+ );
311
+
312
+ expect(on12HourMachine).toBe("Mar 1, 2:30 PM");
313
+ expect(on24HourMachine).toBe("Mar 1, 14:30");
314
+ });
315
+ });
316
+ });
@@ -0,0 +1,53 @@
1
+ import { describe, expect, test } from "@jest/globals";
2
+ import NotificationSettingEventType from "../../../Types/NotificationSetting/NotificationSettingEventType";
3
+
4
+ /*
5
+ * The enum VALUES are what is stored in user_notification_setting.eventType
6
+ * and what the dashboard shows as the row label, so a value is a contract
7
+ * with every existing row and every translation. These pin the two on-call
8
+ * shift reminder members exactly.
9
+ */
10
+ describe("NotificationSettingEventType - on-call shift reminders", () => {
11
+ test("has the 'before shift starts' member with its stored value", () => {
12
+ expect(
13
+ NotificationSettingEventType.SEND_BEFORE_USER_ON_CALL_SHIFT_STARTS,
14
+ ).toBe("Before user's on-call shift starts");
15
+ });
16
+
17
+ test("has the 'shift reassigned' member with its stored value", () => {
18
+ expect(
19
+ NotificationSettingEventType.SEND_WHEN_USER_ON_CALL_SHIFT_IS_REASSIGNED,
20
+ ).toBe("User's upcoming on-call shift is reassigned");
21
+ });
22
+
23
+ test("every value is unique, so no two settings rows can mean two things", () => {
24
+ const values: Array<string> = Object.values(NotificationSettingEventType);
25
+
26
+ expect(new Set(values).size).toBe(values.length);
27
+ });
28
+
29
+ test("every value is non-empty and free of surrounding whitespace", () => {
30
+ for (const value of Object.values(NotificationSettingEventType)) {
31
+ expect(value.trim()).toBe(value);
32
+ expect(value.length).toBeGreaterThan(0);
33
+ }
34
+ });
35
+
36
+ test("the existing on-call members are untouched", () => {
37
+ expect(NotificationSettingEventType.SEND_WHEN_USER_IS_ON_CALL_ROSTER).toBe(
38
+ "When user is on-call roster",
39
+ );
40
+ expect(
41
+ NotificationSettingEventType.SEND_WHEN_USER_IS_NEXT_ON_CALL_ROSTER,
42
+ ).toBe("When user is next on-call roster");
43
+ expect(
44
+ NotificationSettingEventType.SEND_WHEN_USER_IS_ADDED_TO_ON_CALL_POLICY,
45
+ ).toBe("When user is added to on-call policy");
46
+ expect(
47
+ NotificationSettingEventType.SEND_WHEN_USER_IS_REMOVED_FROM_ON_CALL_POLICY,
48
+ ).toBe("When user is removed from on-call policy");
49
+ expect(
50
+ NotificationSettingEventType.SEND_WHEN_USER_IS_NO_LONGER_ACTIVE_ON_ON_CALL_ROSTER,
51
+ ).toBe("When user is no longer active on on-call roster");
52
+ });
53
+ });