@oneuptime/common 12.0.17 → 12.0.19

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 (220) hide show
  1. package/Models/DatabaseModels/EnterpriseLicense.ts +23 -0
  2. package/Models/DatabaseModels/Index.ts +4 -2
  3. package/Models/DatabaseModels/Monitor.ts +39 -9
  4. package/Models/DatabaseModels/UserMicrosoftTeams.ts +344 -0
  5. package/Models/DatabaseModels/UserNotificationRule.ts +144 -8
  6. package/Models/DatabaseModels/UserNotificationSetting.ts +34 -0
  7. package/Models/DatabaseModels/UserOnCallLogTimeline.ts +95 -0
  8. package/Models/DatabaseModels/UserSlack.ts +341 -0
  9. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +9 -0
  10. package/Server/API/UserMicrosoftTeamsAPI.ts +127 -0
  11. package/Server/API/UserSlackAPI.ts +125 -0
  12. package/Server/EnvironmentConfig.ts +12 -107
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1788700000000-RemoveMarketingConversionUploadState.ts +33 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail.ts +51 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1788900000000-RedactStoredMonitorIngestSecrets.ts +117 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1789000000000-AddUserSlackAndMicrosoftTeams.ts +197 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  18. package/Server/Infrastructure/Queue.ts +7 -0
  19. package/Server/Services/BillingService.ts +8 -0
  20. package/Server/Services/EnterpriseLicenseService.ts +60 -0
  21. package/Server/Services/Index.ts +6 -2
  22. package/Server/Services/LlmLogService.ts +25 -9
  23. package/Server/Services/OnCallReadinessService.ts +86 -2
  24. package/Server/Services/ProjectService.ts +67 -0
  25. package/Server/Services/UserMicrosoftTeamsService.ts +208 -0
  26. package/Server/Services/UserNotificationMethodAdminService.ts +167 -5
  27. package/Server/Services/UserNotificationRuleAdminService.ts +40 -6
  28. package/Server/Services/UserNotificationRuleService.ts +589 -11
  29. package/Server/Services/UserNotificationSettingService.ts +138 -0
  30. package/Server/Services/UserService.ts +28 -0
  31. package/Server/Services/UserSlackService.ts +218 -0
  32. package/Server/Services/WorkspaceProjectAuthTokenService.ts +67 -1
  33. package/Server/Services/WorkspaceUserAuthTokenService.ts +73 -0
  34. package/Server/Services/WorkspaceUserNotificationService.ts +190 -0
  35. package/Server/Utils/Marketing/MarketingEventUtil.ts +145 -0
  36. package/Server/Utils/Marketing/MarketingEventWebhook.ts +114 -0
  37. package/Server/Utils/Monitor/MonitorLogUtil.ts +14 -1
  38. package/Server/Utils/Monitor/MonitorPayloadRedaction.ts +321 -0
  39. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +191 -4
  40. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +22 -14
  41. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +22 -11
  42. package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +37 -1
  43. package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +18 -10
  44. package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +17 -0
  45. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +27 -1
  46. package/Tests/Models/DatabaseModels/MonitorSecretKeyColumnAccessControl.test.ts +214 -0
  47. package/Tests/Server/API/OnCallReadinessAPI.test.ts +145 -26
  48. package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +2 -2
  49. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +11 -1
  50. package/Tests/Server/Services/AdminRuleEditGuards.test.ts +22 -8
  51. package/Tests/Server/Services/BillingService.test.ts +20 -0
  52. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +18 -2
  53. package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +5 -1
  54. package/Tests/Server/Services/LlmLogServiceTokenAggregateParams.test.ts +640 -0
  55. package/Tests/Server/Services/NotificationChannelEventCoverage.test.ts +246 -22
  56. package/Tests/Server/Services/NotificationDeletionImpact.test.ts +136 -8
  57. package/Tests/Server/Services/OnCallNotificationFallback.test.ts +191 -8
  58. package/Tests/Server/Services/OnCallReadinessService.test.ts +343 -18
  59. package/Tests/Server/Services/SeverityRuleBackfill.test.ts +5 -1
  60. package/Tests/Server/Services/UserMicrosoftTeamsService.test.ts +343 -0
  61. package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +209 -8
  62. package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +22 -6
  63. package/Tests/Server/Services/UserNotificationRuleDefaultCreation.test.ts +12 -6
  64. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +37 -3
  65. package/Tests/Server/Services/UserNotificationRuleWorkspaceDelivery.test.ts +669 -0
  66. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +410 -0
  67. package/Tests/Server/Services/UserSlackService.test.ts +407 -0
  68. package/Tests/Server/Services/WorkspaceProjectAuthTokenDisconnectCascade.test.ts +224 -0
  69. package/Tests/Server/Services/WorkspaceUserAuthTokenNotificationMethodCascade.test.ts +189 -0
  70. package/Tests/Server/Services/WorkspaceUserNotificationService.test.ts +496 -0
  71. package/Tests/Server/Types/Database/Permissions/AdminNotificationRuleAccess.test.ts +30 -17
  72. package/Tests/Server/Types/Database/Permissions/CreateOwnershipScoping.test.ts +8 -3
  73. package/Tests/Server/Types/Database/Permissions/OwnerOnlyColumns.test.ts +72 -3
  74. package/Tests/Server/Types/Database/Permissions/UserNotificationRuleScoping.test.ts +22 -18
  75. package/Tests/Server/Types/Database/Permissions/WorkspaceMethodStampedColumnCreate.test.ts +178 -0
  76. package/Tests/Server/Utils/Marketing/MarketingEventUtil.test.ts +259 -0
  77. package/Tests/Server/Utils/Marketing/MarketingEventWebhook.test.ts +257 -0
  78. package/Tests/Server/Utils/Monitor/MonitorLogUtilRedaction.test.ts +300 -0
  79. package/Tests/Server/Utils/Monitor/MonitorPayloadRedaction.test.ts +381 -0
  80. package/Tests/Server/Utils/Runbook/RunbookExecutePermission.test.ts +228 -0
  81. package/Tests/Server/Utils/SessionReplay/SessionReplayErasureTombstone.test.ts +189 -0
  82. package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +205 -0
  83. package/Tests/Server/Utils/Telemetry/AppMetrics.test.ts +275 -0
  84. package/Tests/Server/Utils/Telemetry/TelemetryContext.test.ts +279 -0
  85. package/Tests/Server/Utils/Workspace/MicrosoftTeamsDirectMessage.test.ts +454 -0
  86. package/Tests/Types/Kubernetes/KubernetesObjectParsers.test.ts +794 -0
  87. package/Tests/Types/Kubernetes/KubernetesRightSizing.test.ts +53 -0
  88. package/Tests/Types/Measurement/MeasurementAggregationType.test.ts +100 -0
  89. package/Tests/Types/Monitor/MonitorStepConfigHelpers.test.ts +114 -0
  90. package/Tests/Types/Workspace/WorkspaceType.test.ts +53 -0
  91. package/Tests/UI/Utils/NotificationMethodUtil.test.ts +137 -9
  92. package/Tests/UI/Utils/PermissionGate.test.ts +105 -0
  93. package/Tests/Utils/Dashboard/Components/DashboardComponentDefaults.test.ts +257 -0
  94. package/Types/Billing/PayAsYouGoPricing.ts +1 -1
  95. package/Types/Marketing/MarketingEvent.ts +97 -0
  96. package/UI/Utils/NotificationMethodUtil.ts +41 -1
  97. package/UI/Utils/PermissionGate.ts +56 -0
  98. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +24 -0
  99. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
  100. package/build/dist/Models/DatabaseModels/Index.js +4 -2
  101. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  102. package/build/dist/Models/DatabaseModels/Monitor.js +39 -9
  103. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  104. package/build/dist/Models/DatabaseModels/UserMicrosoftTeams.js +363 -0
  105. package/build/dist/Models/DatabaseModels/UserMicrosoftTeams.js.map +1 -0
  106. package/build/dist/Models/DatabaseModels/UserNotificationRule.js +145 -8
  107. package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
  108. package/build/dist/Models/DatabaseModels/UserNotificationSetting.js +38 -0
  109. package/build/dist/Models/DatabaseModels/UserNotificationSetting.js.map +1 -1
  110. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +96 -0
  111. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
  112. package/build/dist/Models/DatabaseModels/UserSlack.js +361 -0
  113. package/build/dist/Models/DatabaseModels/UserSlack.js.map +1 -0
  114. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  115. package/build/dist/Server/API/UserMicrosoftTeamsAPI.js +82 -0
  116. package/build/dist/Server/API/UserMicrosoftTeamsAPI.js.map +1 -0
  117. package/build/dist/Server/API/UserSlackAPI.js +81 -0
  118. package/build/dist/Server/API/UserSlackAPI.js.map +1 -0
  119. package/build/dist/Server/EnvironmentConfig.js +10 -70
  120. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  121. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788700000000-RemoveMarketingConversionUploadState.js +26 -0
  122. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788700000000-RemoveMarketingConversionUploadState.js.map +1 -0
  123. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail.js +37 -0
  124. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail.js.map +1 -0
  125. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788900000000-RedactStoredMonitorIngestSecrets.js +106 -0
  126. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788900000000-RedactStoredMonitorIngestSecrets.js.map +1 -0
  127. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789000000000-AddUserSlackAndMicrosoftTeams.js +78 -0
  128. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789000000000-AddUserSlackAndMicrosoftTeams.js.map +1 -0
  129. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  130. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  131. package/build/dist/Server/Infrastructure/Queue.js +7 -0
  132. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  133. package/build/dist/Server/Services/BillingService.js +6 -0
  134. package/build/dist/Server/Services/BillingService.js.map +1 -1
  135. package/build/dist/Server/Services/EnterpriseLicenseService.js +65 -0
  136. package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
  137. package/build/dist/Server/Services/Index.js +6 -2
  138. package/build/dist/Server/Services/Index.js.map +1 -1
  139. package/build/dist/Server/Services/LlmLogService.js +25 -9
  140. package/build/dist/Server/Services/LlmLogService.js.map +1 -1
  141. package/build/dist/Server/Services/OnCallReadinessService.js +74 -2
  142. package/build/dist/Server/Services/OnCallReadinessService.js.map +1 -1
  143. package/build/dist/Server/Services/ProjectService.js +56 -0
  144. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  145. package/build/dist/Server/Services/UserMicrosoftTeamsService.js +183 -0
  146. package/build/dist/Server/Services/UserMicrosoftTeamsService.js.map +1 -0
  147. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +138 -2
  148. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -1
  149. package/build/dist/Server/Services/UserNotificationRuleAdminService.js +32 -4
  150. package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -1
  151. package/build/dist/Server/Services/UserNotificationRuleService.js +499 -67
  152. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  153. package/build/dist/Server/Services/UserNotificationSettingService.js +118 -0
  154. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  155. package/build/dist/Server/Services/UserService.js +26 -1
  156. package/build/dist/Server/Services/UserService.js.map +1 -1
  157. package/build/dist/Server/Services/UserSlackService.js +195 -0
  158. package/build/dist/Server/Services/UserSlackService.js.map +1 -0
  159. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +64 -1
  160. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
  161. package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js +70 -0
  162. package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js.map +1 -1
  163. package/build/dist/Server/Services/WorkspaceUserNotificationService.js +129 -0
  164. package/build/dist/Server/Services/WorkspaceUserNotificationService.js.map +1 -0
  165. package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js +94 -0
  166. package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js.map +1 -0
  167. package/build/dist/Server/Utils/Marketing/MarketingEventWebhook.js +93 -0
  168. package/build/dist/Server/Utils/Marketing/MarketingEventWebhook.js.map +1 -0
  169. package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js +12 -1
  170. package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js.map +1 -1
  171. package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js +233 -0
  172. package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js.map +1 -0
  173. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +141 -4
  174. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  175. package/build/dist/Types/Billing/PayAsYouGoPricing.js +1 -1
  176. package/build/dist/Types/Billing/PayAsYouGoPricing.js.map +1 -1
  177. package/build/dist/Types/Marketing/MarketingEvent.js +43 -0
  178. package/build/dist/Types/Marketing/MarketingEvent.js.map +1 -0
  179. package/build/dist/UI/Utils/NotificationMethodUtil.js +33 -1
  180. package/build/dist/UI/Utils/NotificationMethodUtil.js.map +1 -1
  181. package/build/dist/UI/Utils/PermissionGate.js +32 -0
  182. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  183. package/package.json +1 -1
  184. package/Models/DatabaseModels/MarketingConversion.ts +0 -410
  185. package/Server/Services/MarketingConversionService.ts +0 -10
  186. package/Server/Utils/Marketing/ConversionUploadProvider.ts +0 -215
  187. package/Server/Utils/Marketing/ConversionUploadProviders.ts +0 -22
  188. package/Server/Utils/Marketing/Providers/GoogleAds.ts +0 -333
  189. package/Server/Utils/Marketing/Providers/LinkedIn.ts +0 -185
  190. package/Server/Utils/Marketing/Providers/Meta.ts +0 -182
  191. package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +0 -223
  192. package/Server/Utils/Marketing/Providers/Reddit.ts +0 -208
  193. package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +0 -315
  194. package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +0 -300
  195. package/Tests/Server/Utils/Marketing/GoogleAds.test.ts +0 -592
  196. package/Tests/Server/Utils/Marketing/LinkedIn.test.ts +0 -282
  197. package/Tests/Server/Utils/Marketing/Meta.test.ts +0 -304
  198. package/Tests/Server/Utils/Marketing/MicrosoftAds.test.ts +0 -263
  199. package/Tests/Server/Utils/Marketing/Reddit.test.ts +0 -259
  200. package/Types/Marketing/MarketingConversion.ts +0 -53
  201. package/build/dist/Models/DatabaseModels/MarketingConversion.js +0 -445
  202. package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +0 -1
  203. package/build/dist/Server/Services/MarketingConversionService.js +0 -9
  204. package/build/dist/Server/Services/MarketingConversionService.js.map +0 -1
  205. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +0 -93
  206. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +0 -1
  207. package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js +0 -20
  208. package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js.map +0 -1
  209. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +0 -221
  210. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +0 -1
  211. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +0 -137
  212. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +0 -1
  213. package/build/dist/Server/Utils/Marketing/Providers/Meta.js +0 -133
  214. package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +0 -1
  215. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +0 -143
  216. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +0 -1
  217. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +0 -145
  218. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +0 -1
  219. package/build/dist/Types/Marketing/MarketingConversion.js +0 -52
  220. package/build/dist/Types/Marketing/MarketingConversion.js.map +0 -1
@@ -17,6 +17,8 @@ import UserPushService from "./UserPushService";
17
17
  import UserService from "./UserService";
18
18
  import UserSmsService from "./UserSmsService";
19
19
  import UserTelegramService from "./UserTelegramService";
20
+ import UserSlackService from "./UserSlackService";
21
+ import UserMicrosoftTeamsService from "./UserMicrosoftTeamsService";
20
22
  import UserWebhookService from "./UserWebhookService";
21
23
  import UserWhatsAppService from "./UserWhatsAppService";
22
24
  import type AuditLogServiceType from "./AuditLogService";
@@ -42,6 +44,8 @@ import UserEmail from "../../Models/DatabaseModels/UserEmail";
42
44
  import UserPush from "../../Models/DatabaseModels/UserPush";
43
45
  import UserSMS from "../../Models/DatabaseModels/UserSMS";
44
46
  import UserTelegram from "../../Models/DatabaseModels/UserTelegram";
47
+ import UserSlack from "../../Models/DatabaseModels/UserSlack";
48
+ import UserMicrosoftTeams from "../../Models/DatabaseModels/UserMicrosoftTeams";
45
49
  import UserWebhook from "../../Models/DatabaseModels/UserWebhook";
46
50
  import UserWhatsApp from "../../Models/DatabaseModels/UserWhatsApp";
47
51
 
@@ -66,7 +70,8 @@ import UserWhatsApp from "../../Models/DatabaseModels/UserWhatsApp";
66
70
  * filters, sort columns appended after the guard had run. The models are still
67
71
  * CurrentUser-only. Nothing in this file changes that, and an administrator's
68
72
  * every direct read or write of UserEmail, UserSMS, UserCall, UserWhatsApp,
69
- * UserTelegram, UserPush and UserWebhook is still refused.
73
+ * UserTelegram, UserSlack, UserMicrosoftTeams, UserPush and UserWebhook is
74
+ * still refused.
70
75
  *
71
76
  * What this file does instead is a NARROW, SERVER-SIDE, AUDITED capability
72
77
  * that runs as root on the admin's behalf and never hands them the row:
@@ -88,7 +93,7 @@ import UserWhatsApp from "../../Models/DatabaseModels/UserWhatsApp";
88
93
  * notification methods page as an unverified method they did not add — on
89
94
  * top of the mail this service sends them.
90
95
  *
91
- * - REMOVE is allowed on all seven channels, because offboarding a stale
96
+ * - REMOVE is allowed on all nine channels, because offboarding a stale
92
97
  * device is a real administrative job and the owner may well be gone. It is
93
98
  * the destructive direction, so it is the one with a preview attached:
94
99
  * UserNotificationRuleService.getNotificationMethodDeletionImpact says how
@@ -100,7 +105,10 @@ import UserWhatsApp from "../../Models/DatabaseModels/UserWhatsApp";
100
105
  * omissions are not oversights. Push is a device token minted by a browser
101
106
  * or a phone at registration time; there is nothing an admin could type.
102
107
  * Telegram needs the account holder to message the bot before a chat id
103
- * exists. Webhook is the one that is deliberately refused rather than
108
+ * exists. Slack and Microsoft Teams are pointers at the owner's own OAuth
109
+ * workspace link, which only the owner can establish — and an admin-created
110
+ * row would be live immediately, since creation is verification for those
111
+ * two. Webhook is the one that is deliberately refused rather than
104
112
  * merely impractical: UserWebhook has no isVerified column at all, so an
105
113
  * admin-created webhook would be live the moment it was written, which is
106
114
  * exactly the silent-redirect this whole design is built to prevent.
@@ -139,7 +147,7 @@ export interface AdminNotificationMethodView {
139
147
 
140
148
  /**
141
149
  * The four channels an administrator may CREATE. See the header for why the
142
- * other three are absent; this enum is the single place that decides, and both
150
+ * other five are absent; this enum is the single place that decides, and both
143
151
  * the API's validation and the service's own dispatch read it.
144
152
  */
145
153
  export enum AdminAddableChannel {
@@ -751,6 +759,160 @@ export class UserNotificationMethodAdminService extends BaseService {
751
759
  });
752
760
  },
753
761
  },
762
+ {
763
+ methodType: ReadinessMethodType.Slack,
764
+ isAdminAddable: false,
765
+ modelType: UserSlack,
766
+ list: async (data: {
767
+ projectId: ObjectID;
768
+ userId: ObjectID;
769
+ }): Promise<Array<AdminNotificationMethodView>> => {
770
+ const rows: Array<UserSlack> = await UserSlackService.findBy({
771
+ query: { projectId: data.projectId, userId: data.userId },
772
+ /*
773
+ * The username only — never slackUserId, which is the addressable
774
+ * target the bot sends to. Same rule OnCallReadinessService
775
+ * follows.
776
+ */
777
+ select: {
778
+ _id: true,
779
+ slackUserName: true,
780
+ isVerified: true,
781
+ createdAt: true,
782
+ },
783
+ sort: { createdAt: SortOrder.Ascending },
784
+ skip: 0,
785
+ limit: LIMIT_PER_PROJECT,
786
+ props: { isRoot: true },
787
+ });
788
+
789
+ return rows.map((row: UserSlack): AdminNotificationMethodView => {
790
+ return this.toView({
791
+ row: row,
792
+ methodType: ReadinessMethodType.Slack,
793
+ isAdminAddable: false,
794
+ identifier: row.slackUserName,
795
+ kind: MaskedIdentifierKind.Handle,
796
+ isVerified: row.isVerified,
797
+ });
798
+ });
799
+ },
800
+ findOwnedRow: async (data: {
801
+ methodId: ObjectID;
802
+ projectId: ObjectID;
803
+ userId: ObjectID;
804
+ }): Promise<AdminNotificationMethodView | null> => {
805
+ const row: UserSlack | null = await UserSlackService.findOneBy({
806
+ query: {
807
+ _id: data.methodId,
808
+ projectId: data.projectId,
809
+ userId: data.userId,
810
+ },
811
+ select: {
812
+ _id: true,
813
+ slackUserName: true,
814
+ isVerified: true,
815
+ },
816
+ props: { isRoot: true },
817
+ });
818
+
819
+ return row
820
+ ? this.toView({
821
+ row: row,
822
+ methodType: ReadinessMethodType.Slack,
823
+ isAdminAddable: false,
824
+ identifier: row.slackUserName,
825
+ kind: MaskedIdentifierKind.Handle,
826
+ isVerified: row.isVerified,
827
+ })
828
+ : null;
829
+ },
830
+ deleteRow: async (data: { methodId: ObjectID }): Promise<void> => {
831
+ await UserSlackService.deleteOneById({
832
+ id: data.methodId,
833
+ props: { isRoot: true },
834
+ });
835
+ },
836
+ },
837
+ {
838
+ methodType: ReadinessMethodType.MicrosoftTeams,
839
+ isAdminAddable: false,
840
+ modelType: UserMicrosoftTeams,
841
+ list: async (data: {
842
+ projectId: ObjectID;
843
+ userId: ObjectID;
844
+ }): Promise<Array<AdminNotificationMethodView>> => {
845
+ const rows: Array<UserMicrosoftTeams> =
846
+ await UserMicrosoftTeamsService.findBy({
847
+ query: { projectId: data.projectId, userId: data.userId },
848
+ /*
849
+ * The display name only — never microsoftTeamsUserId, which is
850
+ * the addressable target the bot sends to. Same rule
851
+ * OnCallReadinessService follows.
852
+ */
853
+ select: {
854
+ _id: true,
855
+ microsoftTeamsUserName: true,
856
+ isVerified: true,
857
+ createdAt: true,
858
+ },
859
+ sort: { createdAt: SortOrder.Ascending },
860
+ skip: 0,
861
+ limit: LIMIT_PER_PROJECT,
862
+ props: { isRoot: true },
863
+ });
864
+
865
+ return rows.map(
866
+ (row: UserMicrosoftTeams): AdminNotificationMethodView => {
867
+ return this.toView({
868
+ row: row,
869
+ methodType: ReadinessMethodType.MicrosoftTeams,
870
+ isAdminAddable: false,
871
+ identifier: row.microsoftTeamsUserName,
872
+ kind: MaskedIdentifierKind.Handle,
873
+ isVerified: row.isVerified,
874
+ });
875
+ },
876
+ );
877
+ },
878
+ findOwnedRow: async (data: {
879
+ methodId: ObjectID;
880
+ projectId: ObjectID;
881
+ userId: ObjectID;
882
+ }): Promise<AdminNotificationMethodView | null> => {
883
+ const row: UserMicrosoftTeams | null =
884
+ await UserMicrosoftTeamsService.findOneBy({
885
+ query: {
886
+ _id: data.methodId,
887
+ projectId: data.projectId,
888
+ userId: data.userId,
889
+ },
890
+ select: {
891
+ _id: true,
892
+ microsoftTeamsUserName: true,
893
+ isVerified: true,
894
+ },
895
+ props: { isRoot: true },
896
+ });
897
+
898
+ return row
899
+ ? this.toView({
900
+ row: row,
901
+ methodType: ReadinessMethodType.MicrosoftTeams,
902
+ isAdminAddable: false,
903
+ identifier: row.microsoftTeamsUserName,
904
+ kind: MaskedIdentifierKind.Handle,
905
+ isVerified: row.isVerified,
906
+ })
907
+ : null;
908
+ },
909
+ deleteRow: async (data: { methodId: ObjectID }): Promise<void> => {
910
+ await UserMicrosoftTeamsService.deleteOneById({
911
+ id: data.methodId,
912
+ props: { isRoot: true },
913
+ });
914
+ },
915
+ },
754
916
  {
755
917
  methodType: ReadinessMethodType.Webhook,
756
918
  isAdminAddable: false,
@@ -966,7 +1128,7 @@ export class UserNotificationMethodAdminService extends BaseService {
966
1128
  * the feature to somebody probing it.
967
1129
  */
968
1130
  throw new BadDataException(
969
- `A project administrator can only add Email, SMS, Call and WhatsApp notification methods for another user. Push, Telegram and webhook methods have to be added by the person who owns the device.`,
1131
+ `A project administrator can only add Email, SMS, Call and WhatsApp notification methods for another user. Push, Telegram, Slack, Microsoft Teams and webhook methods have to be added by the person who owns the device or account.`,
970
1132
  );
971
1133
  }
972
1134
 
@@ -9,6 +9,8 @@ import UserPushService from "./UserPushService";
9
9
  import UserService from "./UserService";
10
10
  import UserSmsService from "./UserSmsService";
11
11
  import UserTelegramService from "./UserTelegramService";
12
+ import UserSlackService from "./UserSlackService";
13
+ import UserMicrosoftTeamsService from "./UserMicrosoftTeamsService";
12
14
  import UserWebhookService from "./UserWebhookService";
13
15
  import UserWhatsAppService from "./UserWhatsAppService";
14
16
  import type AuditLogServiceType from "./AuditLogService";
@@ -74,7 +76,7 @@ import UserNotificationRule from "../../Models/DatabaseModels/UserNotificationRu
74
76
  */
75
77
 
76
78
  /*
77
- * One of the seven ways a rule can name a delivery address, reduced to what the
79
+ * One of the nine ways a rule can name a delivery address, reduced to what the
78
80
  * ownership guard needs: which column carried it (for the error message and the
79
81
  * audit line) and which row it points at.
80
82
  */
@@ -96,7 +98,7 @@ export interface NotificationMethodReference {
96
98
  }
97
99
 
98
100
  /*
99
- * A rule-shaped bag of values to read the guarded columns out of — the seven
101
+ * A rule-shaped bag of values to read the guarded columns out of — the nine
100
102
  * method references AND the ownership column, because both halves of the pair
101
103
  * this file exists to compare arrive through the same payload.
102
104
  *
@@ -231,6 +233,38 @@ export class UserNotificationRuleAdminService extends BaseService {
231
233
  )?.userId;
232
234
  },
233
235
  },
236
+ {
237
+ idColumn: "userSlackId",
238
+ relationColumn: "userSlack",
239
+ label: "Slack",
240
+ findOwnerUserId: async (
241
+ methodId: ObjectID,
242
+ ): Promise<ObjectID | undefined> => {
243
+ return (
244
+ await UserSlackService.findOneById({
245
+ id: methodId,
246
+ select: { _id: true, userId: true },
247
+ props: { isRoot: true },
248
+ })
249
+ )?.userId;
250
+ },
251
+ },
252
+ {
253
+ idColumn: "userMicrosoftTeamsId",
254
+ relationColumn: "userMicrosoftTeams",
255
+ label: "Microsoft Teams",
256
+ findOwnerUserId: async (
257
+ methodId: ObjectID,
258
+ ): Promise<ObjectID | undefined> => {
259
+ return (
260
+ await UserMicrosoftTeamsService.findOneById({
261
+ id: methodId,
262
+ select: { _id: true, userId: true },
263
+ props: { isRoot: true },
264
+ })
265
+ )?.userId;
266
+ },
267
+ },
234
268
  {
235
269
  idColumn: "userPushId",
236
270
  relationColumn: "userPush",
@@ -267,9 +301,9 @@ export class UserNotificationRuleAdminService extends BaseService {
267
301
  }
268
302
 
269
303
  /*
270
- * The seven FK columns, in one place, so a future eighth channel is a single
271
- * entry rather than an eighth thing to remember. A guard that covers six of
272
- * seven covers none: the attacker picks the seventh.
304
+ * The nine FK columns, in one place, so a future tenth channel is a single
305
+ * entry rather than a tenth thing to remember. A guard that covers eight of
306
+ * nine covers none: the attacker picks the ninth.
273
307
  */
274
308
  public getNotificationMethodIdColumns(): Array<string> {
275
309
  return this.getNotificationMethodDescriptors().map(
@@ -372,7 +406,7 @@ export class UserNotificationRuleAdminService extends BaseService {
372
406
  * spelling survives a create.
373
407
  *
374
408
  * This is the same reduction collapseNotificationMethodRelationsOnCreate
375
- * performs for the seven method FKs, and the same one
409
+ * performs for the nine method FKs, and the same one
376
410
  * CreatePermission.checkCreateOwnership performs for this very column — it
377
411
  * validates `user` identically to `userId` and then CLEARS it, because after
378
412
  * clearing there is no second source of truth left to disagree with the