@oneuptime/common 12.0.13 → 12.0.14

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 (376) hide show
  1. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
  2. package/Models/DatabaseModels/UserCall.ts +94 -3
  3. package/Models/DatabaseModels/UserEmail.ts +94 -3
  4. package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
  5. package/Models/DatabaseModels/UserPush.ts +37 -0
  6. package/Models/DatabaseModels/UserSMS.ts +94 -3
  7. package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
  8. package/Server/API/BaseAPI.ts +79 -14
  9. package/Server/API/UserCallAPI.ts +53 -45
  10. package/Server/API/UserEmailAPI.ts +53 -44
  11. package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
  12. package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
  13. package/Server/API/UserPushAPI.ts +126 -2
  14. package/Server/API/UserSmsAPI.ts +53 -44
  15. package/Server/API/UserWhatsAppAPI.ts +53 -50
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  20. package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
  21. package/Server/Services/AnalyticsDatabaseService.ts +169 -0
  22. package/Server/Services/DatabaseService.ts +101 -0
  23. package/Server/Services/LogAggregationService.ts +5 -0
  24. package/Server/Services/PushNotificationService.ts +127 -12
  25. package/Server/Services/TeamMemberService.ts +53 -13
  26. package/Server/Services/UserCallService.ts +55 -24
  27. package/Server/Services/UserEmailService.ts +83 -17
  28. package/Server/Services/UserIncomingCallNumberService.ts +49 -85
  29. package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
  30. package/Server/Services/UserNotificationRuleService.ts +26 -0
  31. package/Server/Services/UserPushService.ts +89 -0
  32. package/Server/Services/UserSmsService.ts +50 -17
  33. package/Server/Services/UserWhatsAppService.ts +48 -15
  34. package/Server/Types/Database/QueryHelper.ts +30 -0
  35. package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
  36. package/Server/Utils/ChannelVerification.ts +510 -0
  37. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
  38. package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
  39. package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
  40. package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
  41. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
  42. package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
  43. package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
  44. package/Server/Utils/TotpAuth.ts +137 -9
  45. package/Server/Utils/UserRegistrationToken.ts +182 -0
  46. package/Server/Utils/VerificationCode.ts +134 -0
  47. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
  48. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
  49. package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
  50. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
  51. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
  52. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +28 -0
  53. package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
  54. package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
  55. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
  56. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
  57. package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
  58. package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
  59. package/Tests/Server/API/UserSmsApi.test.ts +107 -14
  60. package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
  61. package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +315 -0
  62. package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
  63. package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
  64. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
  65. package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
  66. package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
  67. package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
  68. package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
  69. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
  70. package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
  71. package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
  72. package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
  73. package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
  74. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
  75. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
  76. package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
  77. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
  78. package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
  79. package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
  80. package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
  81. package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
  82. package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
  83. package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
  84. package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
  85. package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
  86. package/Tests/Server/Utils/Browser.test.ts +162 -0
  87. package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
  88. package/Tests/Server/Utils/Express.test.ts +371 -0
  89. package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
  90. package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
  91. package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
  92. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
  93. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
  94. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
  95. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
  96. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
  97. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
  98. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
  99. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
  100. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
  101. package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
  102. package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
  103. package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
  104. package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
  105. package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
  106. package/Tests/Types/Call/CallRequest.test.ts +189 -0
  107. package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
  108. package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
  109. package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
  110. package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
  111. package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
  112. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
  113. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
  114. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
  115. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
  116. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
  117. package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
  118. package/Tests/Types/TextRandomGeneration.test.ts +211 -0
  119. package/Tests/UI/Components/Button.test.tsx +175 -1
  120. package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
  121. package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
  122. package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
  123. package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
  124. package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
  125. package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
  126. package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
  127. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
  128. package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
  129. package/Tests/UI/Components/List.test.tsx +9 -2
  130. package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
  131. package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
  132. package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
  133. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
  134. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
  135. package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
  136. package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
  137. package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
  138. package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
  139. package/Tests/UI/Components/Skeleton.test.tsx +71 -0
  140. package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
  141. package/Tests/UI/Components/Tabs.test.tsx +24 -0
  142. package/Tests/UI/Components/Toast.test.tsx +130 -7
  143. package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
  144. package/Tests/UI/Utils/Dropdown.test.ts +423 -0
  145. package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
  146. package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
  147. package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
  148. package/Tests/Utils/API.test.ts +16 -2
  149. package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
  150. package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
  151. package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
  152. package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
  153. package/Types/Email/EmailTemplateType.ts +1 -0
  154. package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
  155. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
  156. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
  157. package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
  158. package/Types/Permission.ts +35 -0
  159. package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
  160. package/Types/PushNotification/PushNotificationMessage.ts +15 -0
  161. package/Types/PushNotification/PushNotificationRequest.ts +8 -16
  162. package/Types/Service/ServiceLanguage.ts +144 -0
  163. package/Types/Text.ts +111 -19
  164. package/UI/Components/Button/Button.tsx +27 -14
  165. package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
  166. package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
  167. package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
  168. package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
  169. package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
  170. package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
  171. package/UI/Components/CommandPalette/Types.ts +49 -0
  172. package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
  173. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  174. package/UI/Components/Feed/FeedItem.tsx +1 -1
  175. package/UI/Components/List/List.tsx +37 -5
  176. package/UI/Components/List/ListSkeleton.tsx +54 -0
  177. package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
  178. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
  179. package/UI/Components/Modal/Modal.tsx +2 -2
  180. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  181. package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
  182. package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
  183. package/UI/Components/Navbar/NavBar.tsx +14 -1
  184. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
  185. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
  186. package/UI/Components/SideOver/SideOver.tsx +37 -2
  187. package/UI/Components/Skeleton/Skeleton.tsx +53 -0
  188. package/UI/Components/Table/Table.tsx +74 -44
  189. package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
  190. package/UI/Components/Tabs/Tab.tsx +1 -1
  191. package/UI/Components/Toast/Toast.tsx +118 -53
  192. package/UI/Components/Toast/ToastInit.tsx +82 -32
  193. package/UI/Styles/Theme.css +40 -0
  194. package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
  195. package/UI/Utils/ModelListCache.ts +188 -0
  196. package/UI/Utils/Project.ts +29 -0
  197. package/Utils/API.ts +6 -1
  198. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
  199. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  200. package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
  201. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  202. package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
  203. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  204. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
  205. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
  206. package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
  207. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  208. package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
  209. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
  211. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  212. package/build/dist/Server/API/BaseAPI.js +69 -13
  213. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  214. package/build/dist/Server/API/UserCallAPI.js +42 -38
  215. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  216. package/build/dist/Server/API/UserEmailAPI.js +42 -38
  217. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  218. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
  219. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  220. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
  221. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
  222. package/build/dist/Server/API/UserPushAPI.js +95 -2
  223. package/build/dist/Server/API/UserPushAPI.js.map +1 -1
  224. package/build/dist/Server/API/UserSmsAPI.js +42 -38
  225. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  226. package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
  227. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  228. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
  233. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
  234. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  236. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
  237. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
  238. package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
  239. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  240. package/build/dist/Server/Services/DatabaseService.js +74 -0
  241. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  242. package/build/dist/Server/Services/LogAggregationService.js +5 -0
  243. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  244. package/build/dist/Server/Services/PushNotificationService.js +69 -30
  245. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  246. package/build/dist/Server/Services/TeamMemberService.js +43 -7
  247. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  248. package/build/dist/Server/Services/UserCallService.js +54 -22
  249. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  250. package/build/dist/Server/Services/UserEmailService.js +78 -17
  251. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  252. package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
  253. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
  254. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
  255. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
  256. package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
  257. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  258. package/build/dist/Server/Services/UserPushService.js +77 -0
  259. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  260. package/build/dist/Server/Services/UserSmsService.js +50 -17
  261. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  262. package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
  263. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  264. package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
  265. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  266. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
  267. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
  268. package/build/dist/Server/Utils/ChannelVerification.js +348 -0
  269. package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
  270. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
  271. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  272. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
  273. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  274. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
  275. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  276. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
  277. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
  278. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
  279. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
  280. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
  281. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
  282. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  283. package/build/dist/Server/Utils/TotpAuth.js +127 -8
  284. package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
  285. package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
  286. package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
  287. package/build/dist/Server/Utils/VerificationCode.js +120 -0
  288. package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
  289. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  290. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  291. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
  292. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  293. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
  294. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  295. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
  296. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  297. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
  298. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
  299. package/build/dist/Types/Permission.js +33 -0
  300. package/build/dist/Types/Permission.js.map +1 -1
  301. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
  302. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
  303. package/build/dist/Types/Service/ServiceLanguage.js +96 -0
  304. package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
  305. package/build/dist/Types/Text.js +82 -17
  306. package/build/dist/Types/Text.js.map +1 -1
  307. package/build/dist/UI/Components/Button/Button.js +22 -14
  308. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  309. package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
  310. package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
  311. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
  312. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
  313. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
  314. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
  315. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
  316. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
  317. package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
  318. package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
  319. package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
  320. package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
  321. package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
  322. package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
  323. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
  324. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
  325. package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
  326. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  327. package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
  328. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  329. package/build/dist/UI/Components/List/List.js +19 -5
  330. package/build/dist/UI/Components/List/List.js.map +1 -1
  331. package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
  332. package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
  333. package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
  334. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
  335. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  336. package/build/dist/UI/Components/Modal/Modal.js +2 -2
  337. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  338. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  339. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
  340. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  341. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
  342. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  343. package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
  344. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  345. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
  346. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  347. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
  348. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  349. package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
  350. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  351. package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
  352. package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
  353. package/build/dist/UI/Components/Table/Table.js +35 -24
  354. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  355. package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
  356. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
  357. package/build/dist/UI/Components/Tabs/Tab.js +1 -1
  358. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  359. package/build/dist/UI/Components/Toast/Toast.js +77 -23
  360. package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
  361. package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
  362. package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
  363. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
  364. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  365. package/build/dist/UI/Utils/ModelListCache.js +126 -0
  366. package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
  367. package/build/dist/UI/Utils/Project.js +24 -1
  368. package/build/dist/UI/Utils/Project.js.map +1 -1
  369. package/build/dist/Utils/API.js +6 -1
  370. package/build/dist/Utils/API.js.map +1 -1
  371. package/jest.config.json +1 -1
  372. package/package.json +2 -3
  373. package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
  374. package/Tests/__mocks__/otpauth.js +0 -30
  375. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
  376. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
@@ -16,7 +16,8 @@ import LIMIT_MAX from "../../Types/Database/LimitMax";
16
16
  import TwilioConfig from "../../Types/CallAndSMS/TwilioConfig";
17
17
  import BadDataException from "../../Types/Exception/BadDataException";
18
18
  import ObjectID from "../../Types/ObjectID";
19
- import Text from "../../Types/Text";
19
+ import TooManyRequestsException from "../../Types/Exception/TooManyRequestsException";
20
+ import ChannelVerification from "../Utils/ChannelVerification";
20
21
  import Project from "../../Models/DatabaseModels/Project";
21
22
  import Model from "../../Models/DatabaseModels/UserCall";
22
23
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
@@ -144,7 +145,8 @@ export class Service extends DatabaseService<Model> {
144
145
  createdItem: Model,
145
146
  ): Promise<Model> {
146
147
  if (!createdItem.isVerified) {
147
- this.sendVerificationCode(createdItem);
148
+ // issue and send the first verification code
149
+ await this.issueAndSendVerificationCode(createdItem);
148
150
  }
149
151
  return createdItem;
150
152
  }
@@ -158,9 +160,10 @@ export class Service extends DatabaseService<Model> {
158
160
  },
159
161
  select: {
160
162
  phone: true,
161
- verificationCode: true,
162
163
  isVerified: true,
163
164
  projectId: true,
165
+ userId: true,
166
+ verificationCodeSentAt: true,
164
167
  },
165
168
  });
166
169
 
@@ -215,23 +218,57 @@ export class Service extends DatabaseService<Model> {
215
218
  );
216
219
  }
217
220
 
218
- // generate new verification code
219
- item.verificationCode = Text.generateRandomNumber(6);
221
+ /*
222
+ * Resend cooldown.
223
+ *
224
+ * Without it, spending the attempt budget on a code and asking for
225
+ * another one is free, which turns the attempt limit into a speed bump
226
+ * rather than a wall — and the resend control doubles as a way to send
227
+ * somebody unsolicited messages as fast as the network allows, at the
228
+ * project's expense.
229
+ */
230
+ const retryAfterSeconds: number =
231
+ ChannelVerification.getResendRetryAfterSeconds({
232
+ lastSentAt: item.verificationCodeSentAt,
233
+ });
220
234
 
221
- await this.updateOneById({
222
- id: item.id!,
223
- props: {
224
- isRoot: true,
225
- },
226
- data: {
227
- verificationCode: item.verificationCode,
228
- },
235
+ if (retryAfterSeconds > 0) {
236
+ throw new TooManyRequestsException(
237
+ `Please wait ${retryAfterSeconds} seconds before requesting another verification code.`,
238
+ );
239
+ }
240
+
241
+ await this.issueAndSendVerificationCode(item);
242
+ }
243
+
244
+ /*
245
+ * Mint a fresh code for this row, store only its digest, and send the
246
+ * plaintext to the channel.
247
+ *
248
+ * The plaintext exists in memory for exactly as long as it takes to hand it
249
+ * to the notification service and is never written anywhere. Everything
250
+ * about why — expiry, the attempt counter, rotation, the resend cooldown —
251
+ * is in Common/Server/Utils/ChannelVerification.ts.
252
+ *
253
+ * This does NOT check whether a send is allowed. Callers decide that:
254
+ * onCreateSuccess because a brand new row has never been sent to, and
255
+ * resendVerificationCode after the cooldown and the channel's own
256
+ * preconditions have passed.
257
+ */
258
+ @CaptureSpan()
259
+ public async issueAndSendVerificationCode(item: Model): Promise<void> {
260
+ const plainCode: string = await ChannelVerification.issueCodeOnItem({
261
+ service: this,
262
+ itemId: item.id!,
229
263
  });
230
264
 
231
- this.sendVerificationCode(item);
265
+ this.sendVerificationCode(item, plainCode);
232
266
  }
233
267
 
234
- public sendVerificationCode(item: Model): void {
268
+ public sendVerificationCode(item: Model, code: string): void {
269
+ // add space to make it more clear and slow down the message
270
+ const spokenCode: string = code.split("").join(" ");
271
+
235
272
  const callRequest: CallRequest = {
236
273
  to: item.phone!,
237
274
  data: [
@@ -239,19 +276,13 @@ export class Service extends DatabaseService<Model> {
239
276
  sayMessage: "This call is from One Uptime.",
240
277
  },
241
278
  {
242
- sayMessage:
243
- "Your verification code is " +
244
- item.verificationCode?.split("").join(" "), // add space to make it more clear and slow down the message
279
+ sayMessage: "Your verification code is " + spokenCode,
245
280
  },
246
281
  {
247
- sayMessage:
248
- "Your verification code is " +
249
- item.verificationCode?.split("").join(" "), // add space to make it more clear and slow down the message
282
+ sayMessage: "Your verification code is " + spokenCode,
250
283
  },
251
284
  {
252
- sayMessage:
253
- "Your verification code is " +
254
- item.verificationCode?.split("").join(" "), // add space to make it more clear and slow down the message
285
+ sayMessage: "Your verification code is " + spokenCode,
255
286
  },
256
287
  {
257
288
  sayMessage: "Thank you for using One Uptime. Goodbye.",
@@ -12,7 +12,8 @@ import LIMIT_MAX from "../../Types/Database/LimitMax";
12
12
  import EmailTemplateType from "../../Types/Email/EmailTemplateType";
13
13
  import BadDataException from "../../Types/Exception/BadDataException";
14
14
  import ObjectID from "../../Types/ObjectID";
15
- import Text from "../../Types/Text";
15
+ import TooManyRequestsException from "../../Types/Exception/TooManyRequestsException";
16
+ import ChannelVerification from "../Utils/ChannelVerification";
16
17
  import Model from "../../Models/DatabaseModels/UserEmail";
17
18
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
18
19
 
@@ -100,8 +101,33 @@ export class Service extends DatabaseService<Model> {
100
101
  createdItem: Model,
101
102
  ): Promise<Model> {
102
103
  if (!createdItem.isVerified) {
103
- // send verification code
104
- this.sendVerificationCode(createdItem);
104
+ // issue and send the first verification code
105
+ const plainCode: string =
106
+ await this.issueAndSendVerificationCode(createdItem);
107
+
108
+ /*
109
+ * TEST-ONLY seam, OFF unless explicitly switched on.
110
+ *
111
+ * The plaintext code is otherwise only ever emailed - never returned by
112
+ * the API - which is deliberate: returning it would let a caller add
113
+ * anybody's address and confirm it instantly, the exact takeover the
114
+ * hashing/expiry/attempt controls exist to stop (see ChannelVerification
115
+ * and VerificationCode). The end-to-end stack has no mailbox to read the
116
+ * emailed code from, so this narrow hatch hands the code back on the
117
+ * create response for it to confirm the address the way a user would.
118
+ *
119
+ * It is gated on an environment variable that is unset in every shipped
120
+ * config and set true ONLY in the CI e2e job (docker-compose passes it
121
+ * through, .github/workflows/test-release.yaml sets it for the SaaS run).
122
+ * In production the flag is absent, this branch never runs, and the code
123
+ * never leaves the mail path.
124
+ */
125
+ if (
126
+ process.env["EXPOSE_VERIFICATION_CODE_IN_API_RESPONSE_FOR_E2E"] ===
127
+ "true"
128
+ ) {
129
+ createdItem.verificationCode = plainCode;
130
+ }
105
131
  }
106
132
 
107
133
  return createdItem;
@@ -116,9 +142,10 @@ export class Service extends DatabaseService<Model> {
116
142
  },
117
143
  select: {
118
144
  email: true,
119
- verificationCode: true,
120
145
  isVerified: true,
121
146
  projectId: true,
147
+ userId: true,
148
+ verificationCodeSentAt: true,
122
149
  },
123
150
  });
124
151
 
@@ -132,29 +159,68 @@ export class Service extends DatabaseService<Model> {
132
159
  throw new BadDataException("Email already verified");
133
160
  }
134
161
 
135
- // generate new verification code
136
- item.verificationCode = Text.generateRandomNumber(6);
162
+ /*
163
+ * Resend cooldown.
164
+ *
165
+ * Without it, spending the attempt budget on a code and asking for
166
+ * another one is free, which turns the attempt limit into a speed bump
167
+ * rather than a wall — and the resend control doubles as a way to send
168
+ * somebody unsolicited messages as fast as the network allows, at the
169
+ * project's expense.
170
+ */
171
+ const retryAfterSeconds: number =
172
+ ChannelVerification.getResendRetryAfterSeconds({
173
+ lastSentAt: item.verificationCodeSentAt,
174
+ });
137
175
 
138
- await this.updateOneById({
139
- id: item.id!,
140
- props: {
141
- isRoot: true,
142
- },
143
- data: {
144
- verificationCode: item.verificationCode,
145
- },
176
+ if (retryAfterSeconds > 0) {
177
+ throw new TooManyRequestsException(
178
+ `Please wait ${retryAfterSeconds} seconds before requesting another verification code.`,
179
+ );
180
+ }
181
+
182
+ await this.issueAndSendVerificationCode(item);
183
+ }
184
+
185
+ /*
186
+ * Mint a fresh code for this row, store only its digest, and send the
187
+ * plaintext to the channel.
188
+ *
189
+ * The plaintext exists in memory for exactly as long as it takes to hand it
190
+ * to the notification service and is never written anywhere. Everything
191
+ * about why — expiry, the attempt counter, rotation, the resend cooldown —
192
+ * is in Common/Server/Utils/ChannelVerification.ts.
193
+ *
194
+ * This does NOT check whether a send is allowed. Callers decide that:
195
+ * onCreateSuccess because a brand new row has never been sent to, and
196
+ * resendVerificationCode after the cooldown and the channel's own
197
+ * preconditions have passed.
198
+ */
199
+ @CaptureSpan()
200
+ public async issueAndSendVerificationCode(item: Model): Promise<string> {
201
+ const plainCode: string = await ChannelVerification.issueCodeOnItem({
202
+ service: this,
203
+ itemId: item.id!,
146
204
  });
147
205
 
148
- this.sendVerificationCode(item);
206
+ this.sendVerificationCode(item, plainCode);
207
+
208
+ /*
209
+ * The plaintext exists here for exactly as long as it takes to hand it to
210
+ * the mailer, and is returned so a caller that has a legitimate reason to
211
+ * see it can - see onCreateSuccess for the one place that does, and the
212
+ * hard gate around it.
213
+ */
214
+ return plainCode;
149
215
  }
150
216
 
151
- public sendVerificationCode(item: Model): void {
217
+ public sendVerificationCode(item: Model, code: string): void {
152
218
  MailService.sendMail(
153
219
  {
154
220
  toEmail: item.email!,
155
221
  templateType: EmailTemplateType.VerificationCode,
156
222
  vars: {
157
- code: item.verificationCode!,
223
+ code: code,
158
224
  subject: "Verify this email address",
159
225
  },
160
226
  subject: "Verify this email address",
@@ -9,7 +9,8 @@ import SmsService from "./SmsService";
9
9
  import TwilioConfig from "../../Types/CallAndSMS/TwilioConfig";
10
10
  import BadDataException from "../../Types/Exception/BadDataException";
11
11
  import ObjectID from "../../Types/ObjectID";
12
- import Text from "../../Types/Text";
12
+ import TooManyRequestsException from "../../Types/Exception/TooManyRequestsException";
13
+ import ChannelVerification from "../Utils/ChannelVerification";
13
14
  import Project from "../../Models/DatabaseModels/Project";
14
15
  import Model from "../../Models/DatabaseModels/UserIncomingCallNumber";
15
16
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
@@ -99,7 +100,8 @@ export class Service extends DatabaseService<Model> {
99
100
  createdItem: Model,
100
101
  ): Promise<Model> {
101
102
  if (!createdItem.isVerified) {
102
- this.sendVerificationCode(createdItem);
103
+ // issue and send the first verification code
104
+ await this.issueAndSendVerificationCode(createdItem);
103
105
  }
104
106
 
105
107
  return createdItem;
@@ -114,10 +116,10 @@ export class Service extends DatabaseService<Model> {
114
116
  },
115
117
  select: {
116
118
  phone: true,
117
- verificationCode: true,
118
119
  isVerified: true,
119
120
  projectId: true,
120
121
  userId: true,
122
+ verificationCodeSentAt: true,
121
123
  },
122
124
  });
123
125
 
@@ -172,30 +174,61 @@ export class Service extends DatabaseService<Model> {
172
174
  );
173
175
  }
174
176
 
175
- // Generate new verification code
176
- item.verificationCode = Text.generateRandomNumber(6);
177
+ /*
178
+ * Resend cooldown.
179
+ *
180
+ * Without it, spending the attempt budget on a code and asking for
181
+ * another one is free, which turns the attempt limit into a speed bump
182
+ * rather than a wall — and the resend control doubles as a way to send
183
+ * somebody unsolicited messages as fast as the network allows, at the
184
+ * project's expense.
185
+ */
186
+ const retryAfterSeconds: number =
187
+ ChannelVerification.getResendRetryAfterSeconds({
188
+ lastSentAt: item.verificationCodeSentAt,
189
+ });
190
+
191
+ if (retryAfterSeconds > 0) {
192
+ throw new TooManyRequestsException(
193
+ `Please wait ${retryAfterSeconds} seconds before requesting another verification code.`,
194
+ );
195
+ }
177
196
 
178
- await this.updateOneById({
179
- id: item.id!,
180
- props: {
181
- isRoot: true,
182
- },
183
- data: {
184
- verificationCode: item.verificationCode,
185
- },
197
+ await this.issueAndSendVerificationCode(item);
198
+ }
199
+
200
+ /*
201
+ * Mint a fresh code for this row, store only its digest, and send the
202
+ * plaintext to the channel.
203
+ *
204
+ * The plaintext exists in memory for exactly as long as it takes to hand it
205
+ * to the notification service and is never written anywhere. Everything
206
+ * about why — expiry, the attempt counter, rotation, the resend cooldown —
207
+ * is in Common/Server/Utils/ChannelVerification.ts.
208
+ *
209
+ * This does NOT check whether a send is allowed. Callers decide that:
210
+ * onCreateSuccess because a brand new row has never been sent to, and
211
+ * resendVerificationCode after the cooldown and the channel's own
212
+ * preconditions have passed.
213
+ */
214
+ @CaptureSpan()
215
+ public async issueAndSendVerificationCode(item: Model): Promise<void> {
216
+ const plainCode: string = await ChannelVerification.issueCodeOnItem({
217
+ service: this,
218
+ itemId: item.id!,
186
219
  });
187
220
 
188
- this.sendVerificationCode(item);
221
+ this.sendVerificationCode(item, plainCode);
189
222
  }
190
223
 
191
- public sendVerificationCode(item: Model): void {
224
+ public sendVerificationCode(item: Model, code: string): void {
192
225
  // Send verification SMS
193
226
  SmsService.sendSms(
194
227
  {
195
228
  to: item.phone!,
196
229
  message:
197
230
  "This message is from OneUptime. Your verification code for incoming call routing is " +
198
- item.verificationCode,
231
+ code,
199
232
  },
200
233
  {
201
234
  projectId: item.projectId,
@@ -206,75 +239,6 @@ export class Service extends DatabaseService<Model> {
206
239
  logger.error(err);
207
240
  });
208
241
  }
209
-
210
- @CaptureSpan()
211
- public async verifyPhoneNumber(
212
- itemId: ObjectID,
213
- userId: ObjectID,
214
- code: string,
215
- ): Promise<void> {
216
- const item: Model | null = await this.findOneById({
217
- id: itemId,
218
- props: {
219
- isRoot: true,
220
- },
221
- select: {
222
- userId: true,
223
- verificationCode: true,
224
- isVerified: true,
225
- projectId: true,
226
- },
227
- });
228
-
229
- if (!item) {
230
- throw new BadDataException("Item not found");
231
- }
232
-
233
- // Check user ID
234
- if (item.userId?.toString() !== userId.toString()) {
235
- throw new BadDataException("Invalid user ID");
236
- }
237
-
238
- if (item.isVerified) {
239
- throw new BadDataException("Phone number is already verified");
240
- }
241
-
242
- if (item.verificationCode !== code) {
243
- throw new BadDataException("Invalid verification code");
244
- }
245
-
246
- // Check if user already has a verified number for this project
247
- const existingVerifiedNumber: Model | null = await this.findOneBy({
248
- query: {
249
- userId: item.userId!,
250
- projectId: item.projectId!,
251
- isVerified: true,
252
- },
253
- select: {
254
- _id: true,
255
- },
256
- props: {
257
- isRoot: true,
258
- },
259
- });
260
-
261
- if (existingVerifiedNumber) {
262
- throw new BadDataException(
263
- "You already have a verified phone number for this project. Please delete the existing one before verifying a new one.",
264
- );
265
- }
266
-
267
- // Mark as verified
268
- await this.updateOneById({
269
- id: itemId,
270
- props: {
271
- isRoot: true,
272
- },
273
- data: {
274
- isVerified: true,
275
- },
276
- });
277
- }
278
242
  }
279
243
 
280
244
  export default new Service();