@oneuptime/common 12.0.13 → 12.0.15

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 (561) hide show
  1. package/Models/DatabaseModels/GlobalOidc.ts +20 -0
  2. package/Models/DatabaseModels/GlobalSso.ts +20 -0
  3. package/Models/DatabaseModels/MarketingConversion.ts +19 -9
  4. package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +46 -0
  5. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
  6. package/Models/DatabaseModels/StatusPage.ts +7 -4
  7. package/Models/DatabaseModels/UserCall.ts +94 -3
  8. package/Models/DatabaseModels/UserEmail.ts +94 -3
  9. package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
  10. package/Models/DatabaseModels/UserPush.ts +37 -0
  11. package/Models/DatabaseModels/UserSMS.ts +94 -3
  12. package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
  13. package/Server/API/BaseAPI.ts +79 -14
  14. package/Server/API/StatusPageAPI.ts +29 -4
  15. package/Server/API/UserCallAPI.ts +53 -45
  16. package/Server/API/UserEmailAPI.ts +53 -44
  17. package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
  18. package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
  19. package/Server/API/UserPushAPI.ts +126 -2
  20. package/Server/API/UserSmsAPI.ts +53 -44
  21. package/Server/API/UserWhatsAppAPI.ts +53 -50
  22. package/Server/EnvironmentConfig.ts +7 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.ts +19 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.ts +40 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  29. package/Server/Middleware/SlackAuthorization.ts +43 -6
  30. package/Server/Middleware/UserAuthorization.ts +236 -26
  31. package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
  32. package/Server/Middleware/WhatsAppAuthorization.ts +43 -3
  33. package/Server/Services/AnalyticsDatabaseService.ts +169 -0
  34. package/Server/Services/DatabaseService.ts +101 -0
  35. package/Server/Services/GlobalOidcProjectService.ts +126 -1
  36. package/Server/Services/GlobalOidcService.ts +132 -0
  37. package/Server/Services/GlobalSsoProjectService.ts +126 -1
  38. package/Server/Services/GlobalSsoService.ts +132 -0
  39. package/Server/Services/LogAggregationService.ts +5 -0
  40. package/Server/Services/PushNotificationService.ts +127 -12
  41. package/Server/Services/TeamMemberService.ts +53 -13
  42. package/Server/Services/UserCallService.ts +55 -24
  43. package/Server/Services/UserEmailService.ts +83 -17
  44. package/Server/Services/UserIncomingCallNumberService.ts +49 -85
  45. package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
  46. package/Server/Services/UserNotificationRuleService.ts +26 -0
  47. package/Server/Services/UserPushService.ts +89 -0
  48. package/Server/Services/UserSmsService.ts +50 -17
  49. package/Server/Services/UserWhatsAppService.ts +48 -15
  50. package/Server/Types/Database/QueryHelper.ts +30 -0
  51. package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
  52. package/Server/Utils/ChannelVerification.ts +510 -0
  53. package/Server/Utils/CronTab.ts +73 -0
  54. package/Server/Utils/GlobalSsoAuthorization.ts +175 -0
  55. package/Server/Utils/Marketing/ConversionUploadProvider.ts +35 -5
  56. package/Server/Utils/Marketing/Providers/GoogleAds.ts +1 -1
  57. package/Server/Utils/Marketing/Providers/LinkedIn.ts +1 -1
  58. package/Server/Utils/Marketing/Providers/Meta.ts +1 -1
  59. package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +1 -1
  60. package/Server/Utils/Marketing/Providers/Reddit.ts +1 -1
  61. package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +48 -33
  62. package/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.ts +35 -30
  63. package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +33 -28
  64. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +475 -47
  65. package/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.ts +35 -30
  66. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +47 -44
  67. package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +33 -28
  68. package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +69 -40
  69. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +35 -29
  70. package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
  71. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +8 -0
  72. package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
  73. package/Server/Utils/Monitor/MonitorResource.ts +161 -21
  74. package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
  75. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
  76. package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
  77. package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
  78. package/Server/Utils/StatusPageContentSecurityPolicy.ts +56 -0
  79. package/Server/Utils/StatusPageCustomizationAccess.ts +117 -0
  80. package/Server/Utils/TotpAuth.ts +137 -9
  81. package/Server/Utils/UserRegistrationToken.ts +182 -0
  82. package/Server/Utils/VerificationCode.ts +134 -0
  83. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
  84. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
  85. package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
  86. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
  87. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
  88. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +28 -0
  89. package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
  90. package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
  91. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
  92. package/Tests/Server/API/StatusPageCustomizationOrigin.test.ts +348 -0
  93. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
  94. package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
  95. package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
  96. package/Tests/Server/API/UserSmsApi.test.ts +107 -14
  97. package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
  98. package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +265 -0
  99. package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +227 -0
  100. package/Tests/Server/Middleware/SlackAuthorization.test.ts +149 -0
  101. package/Tests/Server/Middleware/UserAuthorization.test.ts +27 -13
  102. package/Tests/Server/Middleware/UserAuthorizationGlobalSsoGovernance.test.ts +1455 -0
  103. package/Tests/Server/Middleware/UserAuthorizationSSOProvider.test.ts +91 -2
  104. package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
  105. package/Tests/Server/Middleware/WhatsAppAuthorization.test.ts +233 -0
  106. package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
  107. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
  108. package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
  109. package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
  110. package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
  111. package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
  112. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
  113. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +21 -8
  114. package/Tests/Server/Services/GlobalSsoProviderAuthorization.test.ts +1242 -0
  115. package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
  116. package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
  117. package/Tests/Server/Services/MonitorResourceProbeAgreementHydration.test.ts +459 -0
  118. package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +10 -0
  119. package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
  120. package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
  121. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
  122. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
  123. package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
  124. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
  125. package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
  126. package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
  127. package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
  128. package/Tests/Server/Types/AnalyticsDatabase/AggregateUtilBucketTimestamp.test.ts +416 -0
  129. package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
  130. package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
  131. package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
  132. package/Tests/Server/Types/Database/QueryHelperManyToManyAndEmptyValues.test.ts +551 -0
  133. package/Tests/Server/Types/Database/SelectUtil.test.ts +348 -0
  134. package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
  135. package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
  136. package/Tests/Server/Utils/Browser.test.ts +162 -0
  137. package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
  138. package/Tests/Server/Utils/CronTab.test.ts +116 -0
  139. package/Tests/Server/Utils/Express.test.ts +371 -0
  140. package/Tests/Server/Utils/GlobalSSOToken.test.ts +581 -0
  141. package/Tests/Server/Utils/GlobalSsoAuthorization.test.ts +1401 -0
  142. package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +254 -0
  143. package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +1 -1
  144. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaEvaluateOverTime.test.ts +508 -0
  145. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +30 -9
  146. package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
  147. package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
  148. package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +987 -0
  149. package/Tests/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.test.ts +916 -0
  150. package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
  151. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
  152. package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +382 -0
  153. package/Tests/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.test.ts +1219 -0
  154. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
  155. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
  156. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
  157. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
  158. package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +86 -0
  159. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
  160. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
  161. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
  162. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
  163. package/Tests/Server/Utils/StatusPageContentSecurityPolicy.test.ts +136 -0
  164. package/Tests/Server/Utils/StatusPageCustomizationAccess.test.ts +223 -0
  165. package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
  166. package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
  167. package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
  168. package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
  169. package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
  170. package/Tests/Types/Call/CallRequest.test.ts +189 -0
  171. package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
  172. package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
  173. package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
  174. package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
  175. package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
  176. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
  177. package/Tests/Types/Monitor/MonitorStepConfigHelpers.test.ts +165 -0
  178. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
  179. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
  180. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
  181. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
  182. package/Tests/Types/NetworkDevice/NetworkDeviceLinkRuleScope.test.ts +215 -0
  183. package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
  184. package/Tests/Types/TextRandomGeneration.test.ts +211 -0
  185. package/Tests/UI/Components/Button.test.tsx +175 -1
  186. package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
  187. package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
  188. package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
  189. package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
  190. package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
  191. package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
  192. package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
  193. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
  194. package/Tests/UI/Components/Forms/FormSubmitAnalytics.test.tsx +206 -0
  195. package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
  196. package/Tests/UI/Components/List.test.tsx +9 -2
  197. package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
  198. package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
  199. package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
  200. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
  201. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
  202. package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
  203. package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
  204. package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
  205. package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
  206. package/Tests/UI/Components/Skeleton.test.tsx +71 -0
  207. package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
  208. package/Tests/UI/Components/Tabs.test.tsx +24 -0
  209. package/Tests/UI/Components/Toast.test.tsx +130 -7
  210. package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
  211. package/Tests/UI/Utils/AIChatExport/ConversationMarkdown.test.ts +774 -0
  212. package/Tests/UI/Utils/AIChatExport/MarkdownBlocks.test.ts +791 -0
  213. package/Tests/UI/Utils/AIChatExport/MarkdownSafety.test.ts +544 -0
  214. package/Tests/UI/Utils/Dropdown.test.ts +423 -0
  215. package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
  216. package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
  217. package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
  218. package/Tests/Utils/API.test.ts +16 -2
  219. package/Tests/Utils/Analytics.test.ts +187 -0
  220. package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
  221. package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
  222. package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
  223. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +80 -0
  224. package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +1291 -0
  225. package/Tests/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.test.ts +214 -0
  226. package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
  227. package/Types/Email/EmailTemplateType.ts +1 -0
  228. package/Types/Marketing/MarketingConversion.ts +12 -0
  229. package/Types/Monitor/CriteriaFilter.ts +9 -0
  230. package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
  231. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
  232. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
  233. package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
  234. package/Types/NetworkDevice/NetworkDeviceLinkRuleScope.ts +51 -0
  235. package/Types/Permission.ts +35 -0
  236. package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
  237. package/Types/PushNotification/PushNotificationMessage.ts +15 -0
  238. package/Types/PushNotification/PushNotificationRequest.ts +8 -16
  239. package/Types/Service/ServiceLanguage.ts +144 -0
  240. package/Types/Text.ts +111 -19
  241. package/UI/Components/Button/Button.tsx +27 -14
  242. package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
  243. package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
  244. package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
  245. package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
  246. package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
  247. package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
  248. package/UI/Components/CommandPalette/Types.ts +49 -0
  249. package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
  250. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  251. package/UI/Components/Feed/FeedItem.tsx +1 -1
  252. package/UI/Components/FormModal/BasicFormModal.tsx +12 -0
  253. package/UI/Components/Forms/BasicForm.tsx +13 -1
  254. package/UI/Components/Forms/BasicModelForm.tsx +2 -1
  255. package/UI/Components/Forms/ModelForm.tsx +10 -1
  256. package/UI/Components/Forms/Utils/FormAnalyticsName.ts +39 -0
  257. package/UI/Components/List/List.tsx +37 -5
  258. package/UI/Components/List/ListSkeleton.tsx +54 -0
  259. package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
  260. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
  261. package/UI/Components/Modal/Modal.tsx +2 -2
  262. package/UI/Components/ModelFormModal/ModelFormModal.tsx +6 -1
  263. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  264. package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
  265. package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
  266. package/UI/Components/Navbar/NavBar.tsx +14 -1
  267. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
  268. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
  269. package/UI/Components/SideOver/SideOver.tsx +37 -2
  270. package/UI/Components/Skeleton/Skeleton.tsx +53 -0
  271. package/UI/Components/Table/Table.tsx +74 -44
  272. package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
  273. package/UI/Components/Tabs/Tab.tsx +1 -1
  274. package/UI/Components/Toast/Toast.tsx +118 -53
  275. package/UI/Components/Toast/ToastInit.tsx +82 -32
  276. package/UI/Styles/Theme.css +40 -0
  277. package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
  278. package/UI/Utils/ModelListCache.ts +188 -0
  279. package/UI/Utils/Project.ts +29 -0
  280. package/Utils/API.ts +6 -1
  281. package/Utils/Analytics.ts +55 -2
  282. package/Utils/Monitor/MonitorMetricType.ts +40 -0
  283. package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +587 -37
  284. package/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.ts +115 -0
  285. package/build/dist/Models/DatabaseModels/GlobalOidc.js +21 -0
  286. package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/GlobalSso.js +21 -0
  288. package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/MarketingConversion.js +20 -10
  290. package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +47 -0
  292. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
  294. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  295. package/build/dist/Models/DatabaseModels/StatusPage.js +4 -4
  296. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  297. package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
  298. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  299. package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
  300. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  301. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
  302. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
  303. package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
  304. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  305. package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
  306. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  307. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
  308. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  309. package/build/dist/Server/API/BaseAPI.js +69 -13
  310. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  311. package/build/dist/Server/API/StatusPageAPI.js +25 -4
  312. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  313. package/build/dist/Server/API/UserCallAPI.js +42 -38
  314. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  315. package/build/dist/Server/API/UserEmailAPI.js +42 -38
  316. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  317. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
  318. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  319. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
  320. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
  321. package/build/dist/Server/API/UserPushAPI.js +95 -2
  322. package/build/dist/Server/API/UserPushAPI.js.map +1 -1
  323. package/build/dist/Server/API/UserSmsAPI.js +42 -38
  324. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  325. package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
  326. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  327. package/build/dist/Server/EnvironmentConfig.js +6 -0
  328. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  329. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
  330. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
  331. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
  332. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
  333. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
  334. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
  335. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js +12 -0
  336. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js.map +1 -0
  337. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js +29 -0
  338. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js.map +1 -0
  339. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  340. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  341. package/build/dist/Server/Middleware/SlackAuthorization.js +28 -4
  342. package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
  343. package/build/dist/Server/Middleware/UserAuthorization.js +197 -22
  344. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  345. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
  346. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
  347. package/build/dist/Server/Middleware/WhatsAppAuthorization.js +32 -2
  348. package/build/dist/Server/Middleware/WhatsAppAuthorization.js.map +1 -1
  349. package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
  350. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  351. package/build/dist/Server/Services/DatabaseService.js +74 -0
  352. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  353. package/build/dist/Server/Services/GlobalOidcProjectService.js +105 -0
  354. package/build/dist/Server/Services/GlobalOidcProjectService.js.map +1 -1
  355. package/build/dist/Server/Services/GlobalOidcService.js +127 -0
  356. package/build/dist/Server/Services/GlobalOidcService.js.map +1 -1
  357. package/build/dist/Server/Services/GlobalSsoProjectService.js +105 -0
  358. package/build/dist/Server/Services/GlobalSsoProjectService.js.map +1 -1
  359. package/build/dist/Server/Services/GlobalSsoService.js +127 -0
  360. package/build/dist/Server/Services/GlobalSsoService.js.map +1 -1
  361. package/build/dist/Server/Services/LogAggregationService.js +5 -0
  362. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  363. package/build/dist/Server/Services/PushNotificationService.js +69 -30
  364. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  365. package/build/dist/Server/Services/TeamMemberService.js +43 -7
  366. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  367. package/build/dist/Server/Services/UserCallService.js +54 -22
  368. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  369. package/build/dist/Server/Services/UserEmailService.js +78 -17
  370. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  371. package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
  372. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
  373. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
  374. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
  375. package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
  376. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  377. package/build/dist/Server/Services/UserPushService.js +77 -0
  378. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  379. package/build/dist/Server/Services/UserSmsService.js +50 -17
  380. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  381. package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
  382. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  383. package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
  384. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  385. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
  386. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
  387. package/build/dist/Server/Utils/ChannelVerification.js +348 -0
  388. package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
  389. package/build/dist/Server/Utils/CronTab.js +66 -0
  390. package/build/dist/Server/Utils/CronTab.js.map +1 -1
  391. package/build/dist/Server/Utils/GlobalSsoAuthorization.js +112 -0
  392. package/build/dist/Server/Utils/GlobalSsoAuthorization.js.map +1 -0
  393. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +17 -1
  394. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -1
  395. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +1 -1
  396. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -1
  397. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +1 -1
  398. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -1
  399. package/build/dist/Server/Utils/Marketing/Providers/Meta.js +1 -1
  400. package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -1
  401. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +1 -1
  402. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -1
  403. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +1 -1
  404. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -1
  405. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +37 -35
  406. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
  407. package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js +21 -25
  408. package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js.map +1 -1
  409. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +20 -22
  410. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
  411. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +370 -42
  412. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  413. package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js +21 -25
  414. package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js.map +1 -1
  415. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +34 -37
  416. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  417. package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +21 -25
  418. package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
  419. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +64 -52
  420. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
  421. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +25 -29
  422. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  423. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
  424. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  425. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +8 -0
  426. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  427. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
  428. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  429. package/build/dist/Server/Utils/Monitor/MonitorResource.js +123 -23
  430. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  431. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
  432. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
  433. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
  434. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
  435. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
  436. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
  437. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  438. package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js +39 -0
  439. package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js.map +1 -0
  440. package/build/dist/Server/Utils/StatusPageCustomizationAccess.js +85 -0
  441. package/build/dist/Server/Utils/StatusPageCustomizationAccess.js.map +1 -0
  442. package/build/dist/Server/Utils/TotpAuth.js +127 -8
  443. package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
  444. package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
  445. package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
  446. package/build/dist/Server/Utils/VerificationCode.js +120 -0
  447. package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
  448. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  449. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  450. package/build/dist/Types/Marketing/MarketingConversion.js +10 -0
  451. package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -1
  452. package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
  453. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  454. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
  455. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  456. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
  457. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  458. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
  459. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  460. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
  461. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
  462. package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js +46 -0
  463. package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js.map +1 -0
  464. package/build/dist/Types/Permission.js +33 -0
  465. package/build/dist/Types/Permission.js.map +1 -1
  466. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
  467. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
  468. package/build/dist/Types/Service/ServiceLanguage.js +96 -0
  469. package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
  470. package/build/dist/Types/Text.js +82 -17
  471. package/build/dist/Types/Text.js.map +1 -1
  472. package/build/dist/UI/Components/Button/Button.js +22 -14
  473. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  474. package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
  475. package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
  476. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
  477. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
  478. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
  479. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
  480. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
  481. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
  482. package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
  483. package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
  484. package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
  485. package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
  486. package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
  487. package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
  488. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
  489. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
  490. package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
  491. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  492. package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
  493. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  494. package/build/dist/UI/Components/FormModal/BasicFormModal.js +2 -1
  495. package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
  496. package/build/dist/UI/Components/Forms/BasicForm.js +10 -1
  497. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  498. package/build/dist/UI/Components/Forms/BasicModelForm.js +2 -1
  499. package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
  500. package/build/dist/UI/Components/Forms/ModelForm.js +4 -1
  501. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  502. package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js +33 -0
  503. package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js.map +1 -0
  504. package/build/dist/UI/Components/List/List.js +19 -5
  505. package/build/dist/UI/Components/List/List.js.map +1 -1
  506. package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
  507. package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
  508. package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
  509. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
  510. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  511. package/build/dist/UI/Components/Modal/Modal.js +2 -2
  512. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +2 -1
  513. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  514. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  515. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  516. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
  517. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  518. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
  519. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  520. package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
  521. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  522. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
  523. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  524. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
  525. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  526. package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
  527. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  528. package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
  529. package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
  530. package/build/dist/UI/Components/Table/Table.js +35 -24
  531. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  532. package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
  533. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
  534. package/build/dist/UI/Components/Tabs/Tab.js +1 -1
  535. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  536. package/build/dist/UI/Components/Toast/Toast.js +77 -23
  537. package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
  538. package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
  539. package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
  540. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
  541. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  542. package/build/dist/UI/Utils/ModelListCache.js +126 -0
  543. package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
  544. package/build/dist/UI/Utils/Project.js +24 -1
  545. package/build/dist/UI/Utils/Project.js.map +1 -1
  546. package/build/dist/Utils/API.js +6 -1
  547. package/build/dist/Utils/API.js.map +1 -1
  548. package/build/dist/Utils/Analytics.js +50 -2
  549. package/build/dist/Utils/Analytics.js.map +1 -1
  550. package/build/dist/Utils/Monitor/MonitorMetricType.js +37 -0
  551. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  552. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +318 -37
  553. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -1
  554. package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js +87 -0
  555. package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js.map +1 -0
  556. package/jest.config.json +1 -1
  557. package/package.json +2 -3
  558. package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
  559. package/Tests/__mocks__/otpauth.js +0 -30
  560. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
  561. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
@@ -4,18 +4,138 @@ import Team from "../../Models/DatabaseModels/Team";
4
4
  import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
5
5
  import ObjectID from "../../Types/ObjectID";
6
6
  import CreateBy from "../Types/Database/CreateBy";
7
- import { OnCreate, OnUpdate } from "../Types/Database/Hooks";
7
+ import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
8
8
  import UpdateBy from "../Types/Database/UpdateBy";
9
9
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
10
10
  import validateGlobalProviderProjectTeams, {
11
11
  resolveAttachmentProjectId,
12
12
  } from "../Utils/ValidateGlobalProviderProjectTeams";
13
+ import {
14
+ GLOBAL_SSO_AUTHORIZATION_CACHE_TTL_MS,
15
+ GlobalProviderAttachments,
16
+ clearGlobalSsoAuthorizationCaches,
17
+ doAttachmentsGovernProject,
18
+ globalProviderCacheKey,
19
+ globalSsoAttachmentsCache,
20
+ loadAttachmentsOnce,
21
+ } from "../Utils/GlobalSsoAuthorization";
22
+ import DeleteBy from "../Types/Database/DeleteBy";
13
23
 
14
24
  export class Service extends DatabaseService<Model> {
15
25
  public constructor() {
16
26
  super(Model);
17
27
  }
18
28
 
29
+ /**
30
+ * Whether this provider's attachments cover `projectId`.
31
+ *
32
+ * Only consulted when the provider has `restrictToAttachedProjects` on -
33
+ * attachments are the PROVISIONING allow-list by default, not an access
34
+ * boundary, and reading them as one without the admin asking would lock
35
+ * existing users out of projects they legitimately reach.
36
+ *
37
+ * "No attachment rows at all" means instance-wide, matching the login
38
+ * router's default-all mode. "Rows exist but none are enabled" is a
39
+ * different answer and denies - otherwise an admin disabling the last
40
+ * attachment would WIDEN the provider to every project.
41
+ *
42
+ * Cached for 60s, with concurrent misses sharing one query.
43
+ */
44
+ @CaptureSpan()
45
+ public async doesProviderGovernProject(data: {
46
+ globalSsoId: ObjectID;
47
+ projectId: ObjectID;
48
+ }): Promise<boolean> {
49
+ const key: string = globalProviderCacheKey("sso", data.globalSsoId);
50
+
51
+ const cached: GlobalProviderAttachments | undefined =
52
+ globalSsoAttachmentsCache.get(key);
53
+
54
+ if (cached !== undefined) {
55
+ return doAttachmentsGovernProject(cached, data.projectId);
56
+ }
57
+
58
+ const attachments: GlobalProviderAttachments = await loadAttachmentsOnce(
59
+ key,
60
+ async (): Promise<GlobalProviderAttachments> => {
61
+ /*
62
+ * Fetched WITHOUT the isEnabled filter so a disabled row still counts
63
+ * as "this provider has attachments"; the enabled ones are selected
64
+ * out below.
65
+ */
66
+ const rows: Array<Model> = await this.findBy({
67
+ query: { globalSsoId: data.globalSsoId },
68
+ select: { _id: true, projectId: true, isEnabled: true },
69
+ limit: LIMIT_PER_PROJECT,
70
+ skip: 0,
71
+ props: { isRoot: true },
72
+ });
73
+
74
+ const loaded: GlobalProviderAttachments = {
75
+ hasAnyAttachmentRows: rows.length > 0,
76
+ enabledProjectIds: rows
77
+ .filter((row: Model) => {
78
+ return Boolean(row.isEnabled) && Boolean(row.projectId);
79
+ })
80
+ .map((row: Model) => {
81
+ return row.projectId!.toString();
82
+ }),
83
+ };
84
+
85
+ globalSsoAttachmentsCache.set(
86
+ key,
87
+ loaded,
88
+ GLOBAL_SSO_AUTHORIZATION_CACHE_TTL_MS,
89
+ );
90
+
91
+ return loaded;
92
+ },
93
+ );
94
+
95
+ return doAttachmentsGovernProject(attachments, data.projectId);
96
+ }
97
+
98
+ @CaptureSpan()
99
+ protected override async onBeforeDelete(
100
+ deleteBy: DeleteBy<Model>,
101
+ ): Promise<OnDelete<Model>> {
102
+ // Detaching a project has to take effect now, not in 60s, on this node.
103
+ clearGlobalSsoAuthorizationCaches();
104
+ return { deleteBy, carryForward: null };
105
+ }
106
+
107
+ /*
108
+ * Cleared again AFTER the write commits. A clear that runs before the row
109
+ * lands can be immediately re-filled with the pre-change answer by a
110
+ * concurrent request, handing the old attachment set another full TTL.
111
+ */
112
+ @CaptureSpan()
113
+ protected override async onDeleteSuccess(
114
+ onDelete: OnDelete<Model>,
115
+ _itemIdsBeforeDelete: Array<ObjectID>,
116
+ ): Promise<OnDelete<Model>> {
117
+ clearGlobalSsoAuthorizationCaches();
118
+ return onDelete;
119
+ }
120
+
121
+ @CaptureSpan()
122
+ protected override async onCreateSuccess(
123
+ _onCreate: OnCreate<Model>,
124
+ createdItem: Model,
125
+ ): Promise<Model> {
126
+ clearGlobalSsoAuthorizationCaches();
127
+ return createdItem;
128
+ }
129
+
130
+ @CaptureSpan()
131
+ protected override async onUpdateSuccess(
132
+ onUpdate: OnUpdate<Model>,
133
+ _updatedItemIds: Array<ObjectID>,
134
+ ): Promise<OnUpdate<Model>> {
135
+ clearGlobalSsoAuthorizationCaches();
136
+ return onUpdate;
137
+ }
138
+
19
139
  @CaptureSpan()
20
140
  protected override async onBeforeCreate(
21
141
  createBy: CreateBy<Model>,
@@ -38,6 +158,9 @@ export class Service extends DatabaseService<Model> {
38
158
  projectId,
39
159
  });
40
160
 
161
+ // A new attachment narrows (or widens) which projects the provider governs.
162
+ clearGlobalSsoAuthorizationCaches();
163
+
41
164
  return { createBy, carryForward: null };
42
165
  }
43
166
 
@@ -78,6 +201,8 @@ export class Service extends DatabaseService<Model> {
78
201
  }
79
202
  }
80
203
 
204
+ clearGlobalSsoAuthorizationCaches();
205
+
81
206
  return { updateBy, carryForward: null };
82
207
  }
83
208
  }
@@ -1,10 +1,142 @@
1
1
  import DatabaseService from "./DatabaseService";
2
2
  import Model from "../../Models/DatabaseModels/GlobalSso";
3
+ import ObjectID from "../../Types/ObjectID";
4
+ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
5
+ import CreateBy from "../Types/Database/CreateBy";
6
+ import DeleteBy from "../Types/Database/DeleteBy";
7
+ import UpdateBy from "../Types/Database/UpdateBy";
8
+ import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
9
+ import {
10
+ GLOBAL_SSO_AUTHORIZATION_CACHE_TTL_MS,
11
+ GlobalProviderTrust,
12
+ clearGlobalSsoAuthorizationCaches,
13
+ globalProviderCacheKey,
14
+ globalSsoProviderTrustCache,
15
+ loadTrustOnce,
16
+ } from "../Utils/GlobalSsoAuthorization";
3
17
 
4
18
  export class Service extends DatabaseService<Model> {
5
19
  public constructor() {
6
20
  super(Model);
7
21
  }
22
+
23
+ /**
24
+ * What the SSO-enforcement middleware needs to know about this provider:
25
+ * whether it is still usable at all, and whether the admin opted it into
26
+ * attachment-scoped access.
27
+ *
28
+ * Called on every authenticated request against an SSO-enforced project, so
29
+ * the answer is cached for 60s and concurrent misses share one query.
30
+ * Without this lookup, turning a provider off leaves every token it ever
31
+ * issued working until each one expires - up to thirty days.
32
+ */
33
+ @CaptureSpan()
34
+ public async getProviderTrust(
35
+ providerId: ObjectID,
36
+ ): Promise<GlobalProviderTrust> {
37
+ const key: string = globalProviderCacheKey("sso", providerId);
38
+
39
+ const cached: GlobalProviderTrust | undefined =
40
+ globalSsoProviderTrustCache.get(key);
41
+
42
+ if (cached !== undefined) {
43
+ return cached;
44
+ }
45
+
46
+ return loadTrustOnce(key, async (): Promise<GlobalProviderTrust> => {
47
+ const provider: Model | null = await this.findOneBy({
48
+ query: { _id: providerId.toString() },
49
+ select: {
50
+ _id: true,
51
+ isEnabled: true,
52
+ restrictToAttachedProjects: true,
53
+ },
54
+ props: { isRoot: true },
55
+ });
56
+
57
+ /*
58
+ * A deleted provider and a disabled one are the same answer: no. Both
59
+ * are cached, so a revoked provider does not cost a query per request.
60
+ */
61
+ const trust: GlobalProviderTrust = {
62
+ isUsable: Boolean(provider && provider.isEnabled),
63
+ restrictToAttachedProjects: Boolean(
64
+ provider && provider.restrictToAttachedProjects,
65
+ ),
66
+ };
67
+
68
+ globalSsoProviderTrustCache.set(
69
+ key,
70
+ trust,
71
+ GLOBAL_SSO_AUTHORIZATION_CACHE_TTL_MS,
72
+ );
73
+
74
+ return trust;
75
+ });
76
+ }
77
+
78
+ /*
79
+ * Cache invalidation runs in the SUCCESS hooks, not the before-hooks: a
80
+ * clear that happens before the row is written can be immediately re-filled
81
+ * with the pre-change answer by a concurrent request, which would hand a
82
+ * disabled provider another full TTL of life on the very node that served
83
+ * the disable. Clearing in both is deliberate - the before-hook narrows the
84
+ * window, the success hook closes it.
85
+ *
86
+ * These caches are per-process, so the hooks make a change immediate on the
87
+ * node that served it and the TTL bounds every other node.
88
+ */
89
+
90
+ @CaptureSpan()
91
+ protected override async onBeforeUpdate(
92
+ updateBy: UpdateBy<Model>,
93
+ ): Promise<OnUpdate<Model>> {
94
+ clearGlobalSsoAuthorizationCaches();
95
+ return { updateBy, carryForward: null };
96
+ }
97
+
98
+ @CaptureSpan()
99
+ protected override async onUpdateSuccess(
100
+ onUpdate: OnUpdate<Model>,
101
+ _updatedItemIds: Array<ObjectID>,
102
+ ): Promise<OnUpdate<Model>> {
103
+ clearGlobalSsoAuthorizationCaches();
104
+ return onUpdate;
105
+ }
106
+
107
+ @CaptureSpan()
108
+ protected override async onBeforeDelete(
109
+ deleteBy: DeleteBy<Model>,
110
+ ): Promise<OnDelete<Model>> {
111
+ clearGlobalSsoAuthorizationCaches();
112
+ return { deleteBy, carryForward: null };
113
+ }
114
+
115
+ @CaptureSpan()
116
+ protected override async onDeleteSuccess(
117
+ onDelete: OnDelete<Model>,
118
+ _itemIdsBeforeDelete: Array<ObjectID>,
119
+ ): Promise<OnDelete<Model>> {
120
+ clearGlobalSsoAuthorizationCaches();
121
+ return onDelete;
122
+ }
123
+
124
+ @CaptureSpan()
125
+ protected override async onBeforeCreate(
126
+ createBy: CreateBy<Model>,
127
+ ): Promise<OnCreate<Model>> {
128
+ clearGlobalSsoAuthorizationCaches();
129
+ return { createBy, carryForward: null };
130
+ }
131
+
132
+ @CaptureSpan()
133
+ protected override async onCreateSuccess(
134
+ _onCreate: OnCreate<Model>,
135
+ createdItem: Model,
136
+ ): Promise<Model> {
137
+ clearGlobalSsoAuthorizationCaches();
138
+ return createdItem;
139
+ }
8
140
  }
9
141
 
10
142
  export default new Service();
@@ -282,6 +282,7 @@ export class LogAggregationService {
282
282
  getQuerySettings({
283
283
  maxExecutionTimeInSeconds: 45,
284
284
  timeoutOverflowMode: "break",
285
+ boundScanMemory: true,
285
286
  additionalSettings: { optimize_use_projections: 1 },
286
287
  }),
287
288
  );
@@ -392,6 +393,7 @@ export class LogAggregationService {
392
393
  getQuerySettings({
393
394
  maxExecutionTimeInSeconds: 45,
394
395
  timeoutOverflowMode: "break",
396
+ boundScanMemory: true,
395
397
  }),
396
398
  );
397
399
 
@@ -634,6 +636,7 @@ export class LogAggregationService {
634
636
  getQuerySettings({
635
637
  maxExecutionTimeInSeconds: 45,
636
638
  timeoutOverflowMode: "break",
639
+ boundScanMemory: true,
637
640
  }),
638
641
  );
639
642
 
@@ -714,6 +717,7 @@ export class LogAggregationService {
714
717
  getQuerySettings({
715
718
  maxExecutionTimeInSeconds: 45,
716
719
  timeoutOverflowMode: "break",
720
+ boundScanMemory: true,
717
721
  }),
718
722
  );
719
723
 
@@ -783,6 +787,7 @@ export class LogAggregationService {
783
787
  getQuerySettings({
784
788
  maxExecutionTimeInSeconds: 45,
785
789
  timeoutOverflowMode: "break",
790
+ boundScanMemory: true,
786
791
  }),
787
792
  );
788
793
 
@@ -26,6 +26,7 @@ import UserPush from "../../Models/DatabaseModels/UserPush";
26
26
  import PushNotificationLog from "../../Models/DatabaseModels/PushNotificationLog";
27
27
  import PushNotificationLogService from "./PushNotificationLogService";
28
28
  import PushStatus from "../../Types/PushNotification/PushStatus";
29
+ import AndroidNotificationChannel from "../../Types/PushNotification/AndroidNotificationChannel";
29
30
 
30
31
  /*
31
32
  * The push services the browsers actually use. A Web Push subscription is a
@@ -67,6 +68,43 @@ export interface PushNotificationOptions {
67
68
  teamId?: ObjectID | undefined;
68
69
  }
69
70
 
71
+ /*
72
+ * What Expo needs to be told for a notification to ring through a silenced
73
+ * handset. The two platforms disagree about where the answer lives, so this is
74
+ * computed once and reused by both the direct-SDK and relay send paths.
75
+ *
76
+ * iOS reads the payload: a `sound` object with `critical: true` plus
77
+ * `interruptionLevel: "critical"` is what makes APNs ignore the ringer switch
78
+ * and Focus, and it is refused unless the app carries Apple's critical-alert
79
+ * entitlement.
80
+ *
81
+ * Android ignores all of that and reads the CHANNEL. Sound, importance and Do
82
+ * Not Disturb bypass are baked into the channel when the app creates it and
83
+ * cannot be raised by a payload, so the only lever the server has is which
84
+ * channel id it names.
85
+ */
86
+ export type ExpoPushSound =
87
+ | string
88
+ | null
89
+ | {
90
+ critical?: boolean;
91
+ name?: string | null;
92
+ volume?: number;
93
+ };
94
+
95
+ export type ExpoInterruptionLevel =
96
+ | "active"
97
+ | "critical"
98
+ | "passive"
99
+ | "time-sensitive";
100
+
101
+ export interface ExpoDeliveryOptions {
102
+ channelId: string;
103
+ sound: ExpoPushSound;
104
+ priority: "high";
105
+ interruptionLevel?: ExpoInterruptionLevel;
106
+ }
107
+
70
108
  export default class PushNotificationService {
71
109
  public static isWebPushInitialized = false;
72
110
  private static expoClient: Expo = new Expo(
@@ -408,6 +446,57 @@ export default class PushNotificationService {
408
446
  }
409
447
  }
410
448
 
449
+ /*
450
+ * Volume is pinned rather than exposed as a setting. A critical alert exists
451
+ * to wake somebody, and a responder who has already opted this device in and
452
+ * granted the OS permission has not asked to be woken quietly.
453
+ */
454
+ public static readonly CRITICAL_ALERT_VOLUME: number = 1;
455
+
456
+ public static getExpoDeliveryOptions(
457
+ message: PushNotificationMessage,
458
+ deviceType: PushDeviceType,
459
+ ): ExpoDeliveryOptions {
460
+ const isAndroid: boolean = deviceType === PushDeviceType.Android;
461
+ const isCritical: boolean = Boolean(message.isCriticalAlert);
462
+
463
+ /*
464
+ * iOS has no channels, so "default" here is the payload's own sound rather
465
+ * than a channel id. Android without the critical flag stays on
466
+ * oncall_high, which is what every push has used until now.
467
+ */
468
+ const channelId: string = isAndroid
469
+ ? isCritical
470
+ ? AndroidNotificationChannel.Critical
471
+ : AndroidNotificationChannel.High
472
+ : "default";
473
+
474
+ if (!isCritical) {
475
+ return {
476
+ channelId: channelId,
477
+ sound: "default",
478
+ priority: "high",
479
+ };
480
+ }
481
+
482
+ return {
483
+ channelId: channelId,
484
+ /*
485
+ * Sent to Android too, and harmlessly ignored there. Expo forwards it to
486
+ * APNs where it is the whole mechanism, and to FCM where the channel has
487
+ * already decided the sound; keeping one shape avoids a per-platform
488
+ * branch that could silently drop the iOS half.
489
+ */
490
+ sound: {
491
+ critical: true,
492
+ name: "default",
493
+ volume: PushNotificationService.CRITICAL_ALERT_VOLUME,
494
+ },
495
+ priority: "high",
496
+ interruptionLevel: "critical",
497
+ };
498
+ }
499
+
411
500
  private static async sendExpoPushNotification(
412
501
  expoPushToken: string,
413
502
  message: PushNotificationMessage,
@@ -430,8 +519,10 @@ export default class PushNotificationService {
430
519
  dataPayload["url"] = message.url || message.clickAction || "";
431
520
  }
432
521
 
433
- const channelId: string =
434
- deviceType === PushDeviceType.Android ? "oncall_high" : "default";
522
+ const delivery: ExpoDeliveryOptions = this.getExpoDeliveryOptions(
523
+ message,
524
+ deviceType,
525
+ );
435
526
 
436
527
  // If EXPO_ACCESS_TOKEN is not set, relay through the push notification gateway
437
528
  if (!ExpoAccessToken) {
@@ -439,7 +530,7 @@ export default class PushNotificationService {
439
530
  expoPushToken,
440
531
  message,
441
532
  dataPayload,
442
- channelId,
533
+ delivery,
443
534
  deviceType,
444
535
  );
445
536
  return;
@@ -452,9 +543,12 @@ export default class PushNotificationService {
452
543
  title: message.title,
453
544
  body: message.body,
454
545
  data: dataPayload,
455
- sound: "default",
456
- priority: "high",
457
- channelId: channelId,
546
+ sound: delivery.sound,
547
+ priority: delivery.priority,
548
+ channelId: delivery.channelId,
549
+ ...(delivery.interruptionLevel
550
+ ? { interruptionLevel: delivery.interruptionLevel }
551
+ : {}),
458
552
  };
459
553
 
460
554
  const tickets: ExpoPushTicket[] =
@@ -500,7 +594,7 @@ export default class PushNotificationService {
500
594
  expoPushToken: string,
501
595
  message: PushNotificationMessage,
502
596
  dataPayload: { [key: string]: string },
503
- channelId: string,
597
+ delivery: ExpoDeliveryOptions,
504
598
  deviceType: PushDeviceType,
505
599
  ): Promise<void> {
506
600
  logger.info(
@@ -516,9 +610,19 @@ export default class PushNotificationService {
516
610
  title: message.title || "",
517
611
  body: message.body || "",
518
612
  data: dataPayload,
519
- sound: "default",
520
- priority: "high",
521
- channelId: channelId,
613
+ /*
614
+ * The relay re-sends exactly what it is given, so a critical page
615
+ * that loses its sound object here arrives on the responder's
616
+ * phone as an ordinary silent notification. That is the failure
617
+ * this feature exists to prevent, so the whole delivery shape
618
+ * crosses the wire rather than the channel id alone.
619
+ */
620
+ sound: delivery.sound,
621
+ priority: delivery.priority,
622
+ channelId: delivery.channelId,
623
+ ...(delivery.interruptionLevel
624
+ ? { interruptionLevel: delivery.interruptionLevel }
625
+ : {}),
522
626
  },
523
627
  });
524
628
 
@@ -552,9 +656,10 @@ export default class PushNotificationService {
552
656
  title?: string;
553
657
  body?: string;
554
658
  data?: { [key: string]: string };
555
- sound?: string;
659
+ sound?: ExpoPushSound;
556
660
  priority?: string;
557
661
  channelId?: string;
662
+ interruptionLevel?: ExpoInterruptionLevel;
558
663
  }): Promise<void> {
559
664
  if (!ExpoAccessToken) {
560
665
  throw new Error(
@@ -562,14 +667,24 @@ export default class PushNotificationService {
562
667
  );
563
668
  }
564
669
 
670
+ /*
671
+ * `sound: null` is a caller asking for a silent notification and has to
672
+ * survive, so the fallback tests for undefined rather than falsiness.
673
+ */
674
+ const sound: ExpoPushSound =
675
+ data.sound === undefined ? "default" : data.sound;
676
+
565
677
  const expoPushMessage: ExpoPushMessage = {
566
678
  to: data.to,
567
679
  title: data.title || "",
568
680
  body: data.body || "",
569
681
  data: data.data || {},
570
- sound: (data.sound as "default" | null) || "default",
682
+ sound: sound,
571
683
  priority: (data.priority as "default" | "normal" | "high") || "high",
572
684
  channelId: data.channelId || "default",
685
+ ...(data.interruptionLevel
686
+ ? { interruptionLevel: data.interruptionLevel }
687
+ : {}),
573
688
  };
574
689
 
575
690
  const tickets: ExpoPushTicket[] =
@@ -10,6 +10,7 @@ import UpdateBy from "../Types/Database/UpdateBy";
10
10
  import Errors from "../Utils/Errors";
11
11
  import logger, { LogAttributes } from "../Utils/Logger";
12
12
  import ProductAnalytics from "../Utils/ProductAnalytics";
13
+ import UserRegistrationToken from "../Utils/UserRegistrationToken";
13
14
  import AccessTokenService from "./AccessTokenService";
14
15
  import BillingService from "./BillingService";
15
16
  import DatabaseService from "./DatabaseService";
@@ -166,8 +167,23 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
166
167
  ? (createBy.miscDataProps["name"] as string).trim()
167
168
  : undefined;
168
169
 
169
- let user: User | null = await UserService.findByEmail(email, {
170
- isRoot: true,
170
+ /*
171
+ * `password` comes back too, because whether this person has finished
172
+ * registering decides both which link the invitation carries and whether
173
+ * that link needs a registration token. UserService.findByEmail selects
174
+ * only the id, so it cannot answer that.
175
+ */
176
+ let user: User | null = await UserService.findOneBy({
177
+ query: {
178
+ email: email,
179
+ },
180
+ select: {
181
+ _id: true,
182
+ password: true,
183
+ },
184
+ props: {
185
+ isRoot: true,
186
+ },
171
187
  });
172
188
 
173
189
  let isNewUser: boolean = false;
@@ -228,6 +244,39 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
228
244
  const host: Hostname = await DatabaseConfig.getHost();
229
245
  const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
230
246
 
247
+ /*
248
+ * "Still has to register", not "we just created the row". Someone
249
+ * invited to a second project before they ever signed up already has a
250
+ * user row and still has no password, and used to be sent the sign-in
251
+ * link — which they could not use, having no password to sign in with.
252
+ */
253
+ const needsRegistration: boolean = isNewUser || !user.password;
254
+
255
+ /*
256
+ * The token is what lets the recipient claim this account, so it exists
257
+ * only on the link inside this email and only for someone who has not
258
+ * registered yet. An already-registered invitee gets the plain link;
259
+ * they sign in instead, and minting a claim token for an account that
260
+ * cannot be claimed would just be a spare key lying around.
261
+ */
262
+ const registerLink: string = needsRegistration
263
+ ? (
264
+ await UserRegistrationToken.generateRegistrationLink({
265
+ userId: user.id!,
266
+ email: email,
267
+ })
268
+ ).toString()
269
+ : URL.fromString(
270
+ new URL(
271
+ httpProtocol,
272
+ host,
273
+ new Route(AccountsRoute.toString()),
274
+ ).toString(),
275
+ )
276
+ .addRoute("/register")
277
+ .addQueryParam("email", email.toString(), true)
278
+ .toString();
279
+
231
280
  MailService.sendMail(
232
281
  {
233
282
  toEmail: email,
@@ -240,17 +289,8 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
240
289
  new Route(AccountsRoute.toString()),
241
290
  ).toString(),
242
291
  ).toString(),
243
- registerLink: URL.fromString(
244
- new URL(
245
- httpProtocol,
246
- host,
247
- new Route(AccountsRoute.toString()),
248
- ).toString(),
249
- )
250
- .addRoute("/register")
251
- .addQueryParam("email", email.toString(), true)
252
- .toString(),
253
- isNewUser: isNewUser.toString(),
292
+ registerLink: registerLink,
293
+ isNewUser: needsRegistration.toString(),
254
294
  /*
255
295
  * An auto-accepted member has nothing left to accept, so the
256
296
  * template drops the "sign in to accept your invitation" framing