@oneuptime/common 11.7.0 → 11.7.2
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.
- package/Models/DatabaseModels/DashboardDomain.ts +1 -0
- package/Models/DatabaseModels/Incident.ts +2 -0
- package/Models/DatabaseModels/IncidentEpisode.ts +1 -0
- package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +1 -0
- package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentPublicNote.ts +1 -0
- package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
- package/Models/DatabaseModels/Monitor.ts +1 -0
- package/Models/DatabaseModels/MonitorStatusTimeline.ts +1 -0
- package/Models/DatabaseModels/NetworkSite.ts +1 -0
- package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +1 -0
- package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +1 -0
- package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +2 -0
- package/Models/DatabaseModels/Probe.ts +13 -13
- package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -0
- package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +1 -0
- package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
- package/Models/DatabaseModels/ScheduledMaintenanceTemplate.ts +1 -0
- package/Models/DatabaseModels/StatusPage.ts +1 -0
- package/Models/DatabaseModels/StatusPageAnnouncement.ts +1 -0
- package/Models/DatabaseModels/StatusPageDomain.ts +1 -0
- package/Models/DatabaseModels/WorkspaceNotificationSummary.ts +1 -0
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +11 -0
- package/Server/API/BaseAPI.ts +17 -1
- package/Server/API/CommonAPI.ts +32 -0
- package/Server/API/MicrosoftTeamsAPI.ts +99 -2
- package/Server/API/ProbeAPI.ts +2 -0
- package/Server/API/SlackAPI.ts +62 -0
- package/Server/API/StatusPageAPI.ts +157 -192
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785140242697-AddHotQueryIndexes.ts +89 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785148065137-AddHotQueryIndexesSecondPass.ts +61 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785240000000-RepairCrossProjectMonitorStatusReferences.ts +280 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Services/DatabaseService.ts +11 -3
- package/Server/Services/MonitorGroupService.ts +145 -0
- package/Server/Services/MonitorService.ts +231 -30
- package/Server/Services/ProbeService.ts +319 -16
- package/Server/Services/StatusPageService.ts +72 -42
- package/Server/Services/WorkspaceNotificationRuleService.ts +232 -2
- package/Server/Utils/Database/PostgresErrorTranslator.ts +131 -0
- package/Server/Utils/Monitor/MonitorResource.ts +88 -35
- package/Server/Utils/Monitor/MonitorStatusTimeline.ts +21 -1
- package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +158 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +706 -6
- package/Tests/Models/DatabaseModels/ProbeColumnAccessControl.test.ts +103 -0
- package/Tests/Server/API/BaseAPIUpdateNoOp.test.ts +135 -0
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +317 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +228 -0
- package/Tests/Server/API/ProbeAPI.test.ts +6 -0
- package/Tests/Server/API/ZZVerifyChatsAuth.test.ts +167 -0
- package/Tests/Server/Services/AddHotQueryIndexesMigration.test.ts +255 -0
- package/Tests/Server/Services/AddHotQueryIndexesSecondPassMigration.test.ts +258 -0
- package/Tests/Server/Services/DatabaseServiceSanitizeUpdateData.test.ts +1 -1
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +121 -0
- package/Tests/Server/Services/HeartbeatWriteFastPathSafety.test.ts +200 -0
- package/Tests/Server/Services/HookFreeWriteSafetySecondPass.test.ts +181 -0
- package/Tests/Server/Services/MonitorGroupServiceBatchedStatuses.test.ts +513 -0
- package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +492 -0
- package/Tests/Server/Services/MonitorServiceProbeSelection.test.ts +401 -0
- package/Tests/Server/Services/MonitorStatusTimelineFastPath.test.ts +453 -0
- package/Tests/Server/Services/ProbeAuthKeyCacheAndHeartbeat.test.ts +679 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +3 -3
- package/Tests/Server/Services/StatusPageDomainResolutionCache.test.ts +245 -0
- package/Tests/Server/Services/StatusPageOverviewTimelineWindow.test.ts +283 -0
- package/Tests/Server/Services/StatusPageServiceMcp.test.ts +17 -1
- package/Tests/Server/Services/StatusPageServiceMonitorGroupBatching.test.ts +331 -0
- package/Tests/Server/Services/UserOnCallLogClaimNotificationRule.test.ts +12 -12
- package/Tests/Server/Services/WorkspaceNotificationRuleChats.test.ts +1390 -0
- package/Tests/Server/Utils/AI/Insights/InsightFixRouting.test.ts +4 -4
- package/Tests/Server/Utils/AI/Insights/InsightScanner.test.ts +2 -2
- package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +1 -3
- package/Tests/Server/Utils/AI/Insights/InsightStoreHardening.test.ts +1 -3
- package/Tests/Server/Utils/AI/Insights/InsightTriage.test.ts +1 -1
- package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +5 -5
- package/Tests/Server/Utils/Alert/AlertPrivacyFilter.test.ts +187 -0
- package/Tests/Server/Utils/AlertEpisode/AlertEpisodePrivacyFilter.test.ts +170 -0
- package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +125 -0
- package/Tests/Server/Utils/Incident/IncidentPrivacyFilter.test.ts +264 -0
- package/Tests/Server/Utils/IncidentEpisode/IncidentEpisodePrivacyFilter.test.ts +175 -0
- package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +181 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +1 -1
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +2 -2
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelsList.test.ts +341 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +2175 -0
- package/Tests/Server/Utils/Workspace/SlackChannelsList.test.ts +585 -0
- package/Tests/Types/Billing/MeteredPlan.test.ts +46 -0
- package/Tests/Types/DateUserTimezone.test.ts +205 -0
- package/Tests/Types/DateUserTimezoneOverridesBrowser.test.ts +73 -0
- package/Tests/Types/Workspace/NotificationRules/NotificationRuleCondition.test.ts +219 -1
- package/Tests/UI/Components/BulkUpdateForm.test.tsx +174 -0
- package/Tests/UI/Components/CardModelDetailEdit.test.tsx +315 -0
- package/Tests/UI/Components/ModelDetailSelect.test.tsx +229 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkSelectAll.test.tsx +1258 -0
- package/Tests/UI/Components/ModelTableExportFromColumns.test.ts +153 -0
- package/Tests/UI/Components/MonacoLoader.test.ts +67 -0
- package/Tests/UI/Components/MonacoRuntime.test.ts +121 -0
- package/Tests/UI/Components/TableBulkCsvExport.test.tsx +212 -3
- package/Tests/UI/Components/TimePicker/TimePicker.test.tsx +11 -0
- package/Tests/UI/Utils/Project.test.ts +809 -0
- package/Tests/UI/Utils/TableColumnsToCsv.test.ts +360 -0
- package/Tests/Utils/Alerts/AlertMetricType.test.ts +143 -0
- package/Tests/Utils/Dashboard/VariableUrlState.test.ts +219 -0
- package/Tests/Utils/Incident/IncidentMetricType.test.ts +174 -0
- package/Tests/Utils/Monitor/MonitorProbeSelectionUtil.test.ts +145 -0
- package/Tests/Utils/StatusPage/ResourceUptime.test.ts +263 -0
- package/Types/Date.ts +119 -50
- package/Types/Workspace/NotificationRules/BaseNotificationRule.ts +4 -0
- package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +25 -10
- package/Types/Workspace/WorkspaceMessagePayload.ts +1 -0
- package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +63 -8
- package/UI/Components/CodeEditor/CodeEditor.tsx +3 -0
- package/UI/Components/CodeEditor/MonacoLoader.ts +36 -0
- package/UI/Components/Forms/Fields/FormField.tsx +13 -3
- package/UI/Components/Forms/ModelForm.tsx +41 -18
- package/UI/Components/Input/Input.tsx +6 -1
- package/UI/Components/ModelDetail/CardModelDetail.tsx +23 -1
- package/UI/Components/ModelDetail/ModelDetail.tsx +46 -1
- package/UI/Components/ModelTable/BaseModelTable.tsx +300 -30
- package/UI/Components/ModelTable/Column.ts +12 -0
- package/UI/Components/ModelTable/ExportFromColumns.ts +57 -0
- package/UI/Components/Navbar/NavBar.tsx +66 -1
- package/UI/Components/Table/Table.tsx +52 -13
- package/UI/Components/Table/Types/Column.ts +18 -0
- package/UI/Components/TimePicker/TimePicker.tsx +8 -4
- package/UI/Utils/Project.ts +214 -18
- package/UI/Utils/TableColumnsToCsv.ts +86 -6
- package/UI/Utils/User.ts +19 -0
- package/UI/esbuild-config.js +34 -0
- package/Utils/Monitor/MonitorProbeSelectionUtil.ts +72 -0
- package/build/dist/Models/DatabaseModels/DashboardDomain.js +1 -0
- package/build/dist/Models/DatabaseModels/DashboardDomain.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js +2 -0
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +1 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSite.js +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +1 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +2 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Probe.js +13 -13
- package/build/dist/Models/DatabaseModels/Probe.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +1 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +1 -0
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageDomain.js +1 -0
- package/build/dist/Models/DatabaseModels/StatusPageDomain.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceNotificationSummary.js +1 -0
- package/build/dist/Models/DatabaseModels/WorkspaceNotificationSummary.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +12 -1
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +21 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +72 -2
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ProbeAPI.js +2 -0
- package/build/dist/Server/API/ProbeAPI.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +44 -0
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +98 -152
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785140242697-AddHotQueryIndexes.js +36 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785140242697-AddHotQueryIndexes.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785148065137-AddHotQueryIndexesSecondPass.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785148065137-AddHotQueryIndexesSecondPass.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785240000000-RepairCrossProjectMonitorStatusReferences.js +254 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785240000000-RepairCrossProjectMonitorStatusReferences.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +10 -2
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/MonitorGroupService.js +118 -0
- package/build/dist/Server/Services/MonitorGroupService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +198 -24
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +238 -9
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +46 -39
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +178 -3
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +80 -0
- package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +67 -29
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +31 -14
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +117 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +549 -7
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/Date.js +106 -35
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +17 -7
- package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +37 -11
- package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +2 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/MonacoLoader.js +34 -0
- package/build/dist/UI/Components/CodeEditor/MonacoLoader.js.map +1 -0
- package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -3
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +37 -17
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +6 -1
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +22 -1
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/ModelDetail.js +31 -1
- package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +234 -21
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ExportFromColumns.js +30 -0
- package/build/dist/UI/Components/ModelTable/ExportFromColumns.js.map +1 -0
- package/build/dist/UI/Components/Navbar/NavBar.js +39 -1
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/Table/Table.js +31 -11
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/TimePicker/TimePicker.js +4 -4
- package/build/dist/UI/Components/TimePicker/TimePicker.js.map +1 -1
- package/build/dist/UI/Utils/Project.js +161 -15
- package/build/dist/UI/Utils/Project.js.map +1 -1
- package/build/dist/UI/Utils/TableColumnsToCsv.js +67 -6
- package/build/dist/UI/Utils/TableColumnsToCsv.js.map +1 -1
- package/build/dist/UI/Utils/User.js +19 -0
- package/build/dist/UI/Utils/User.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorProbeSelectionUtil.js +52 -0
- package/build/dist/Utils/Monitor/MonitorProbeSelectionUtil.js.map +1 -0
- package/package.json +4 -3
- package/Server/Infrastructure/Postgres/SchemaMigrations/1773414578773-MigrationName.ts +0 -79
- package/Server/Infrastructure/Postgres/SchemaMigrations/1773500000000-MigrationName.ts +0 -41
- package/Server/Infrastructure/Postgres/SchemaMigrations/1776886248361-MigrationName.ts +0 -17
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773414578773-MigrationName.js +0 -34
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773414578773-MigrationName.js.map +0 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773500000000-MigrationName.js +0 -22
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773500000000-MigrationName.js.map +0 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776886248361-MigrationName.js +0 -12
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776886248361-MigrationName.js.map +0 -1
|
@@ -28,8 +28,9 @@ import UserService from "../../../Services/UserService";
|
|
|
28
28
|
// Import database utilities
|
|
29
29
|
import QueryHelper from "../../../Types/Database/QueryHelper";
|
|
30
30
|
import SortOrder from "../../../../Types/BaseDatabase/SortOrder";
|
|
31
|
+
import LIMIT_MAX from "../../../../Types/Database/LimitMax";
|
|
31
32
|
// Bot Framework SDK imports
|
|
32
|
-
import { CloudAdapter, ConfigurationBotFrameworkAuthentication, TeamsActivityHandler, MessageFactory, } from "botbuilder";
|
|
33
|
+
import { CloudAdapter, ConfigurationBotFrameworkAuthentication, TeamsActivityHandler, TeamsInfo, MessageFactory, } from "botbuilder";
|
|
33
34
|
// Teams action handlers and types
|
|
34
35
|
import MicrosoftTeamsAuthAction from "./Actions/Auth";
|
|
35
36
|
import MicrosoftTeamsIncidentActions from "./Actions/Incident";
|
|
@@ -227,8 +228,28 @@ class MicrosoftTeamsUtil extends WorkspaceBase {
|
|
|
227
228
|
const now = OneUptimeDate.getCurrentDate();
|
|
228
229
|
const expiryDate = OneUptimeDate.addRemoveSeconds(now, expiresIn - 300); // Subtrutes buffer
|
|
229
230
|
logger.debug(`Token expiry calculated: ${OneUptimeDate.toString(expiryDate)}`);
|
|
230
|
-
|
|
231
|
-
|
|
231
|
+
/*
|
|
232
|
+
* Merge the token fields into a FRESH read of miscData instead of the
|
|
233
|
+
* snapshot taken before the OAuth round-trip. The snapshot can be
|
|
234
|
+
* seconds old, and writing it back verbatim would erase concurrent
|
|
235
|
+
* miscData updates — in particular chats captured into availableChats
|
|
236
|
+
* by bot install events, which cannot be re-derived from Graph.
|
|
237
|
+
*/
|
|
238
|
+
let latestMiscData = data.miscData;
|
|
239
|
+
try {
|
|
240
|
+
const latestProjectAuth = await WorkspaceProjectAuthTokenService.getProjectAuth({
|
|
241
|
+
projectId: data.projectId,
|
|
242
|
+
workspaceType: WorkspaceType.MicrosoftTeams,
|
|
243
|
+
});
|
|
244
|
+
if (latestProjectAuth === null || latestProjectAuth === void 0 ? void 0 : latestProjectAuth.miscData) {
|
|
245
|
+
latestMiscData = latestProjectAuth.miscData;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
logger.debug("Could not re-read miscData before token refresh write");
|
|
250
|
+
logger.debug(err);
|
|
251
|
+
}
|
|
252
|
+
const updatedMiscData = Object.assign(Object.assign({}, latestMiscData), { appAccessToken: newAccessToken, appAccessTokenExpiresAt: OneUptimeDate.toString(expiryDate), lastAppTokenIssuedAt: OneUptimeDate.toString(now), tenantId: data.tenantId });
|
|
232
253
|
logger.debug("Saving updated token to database");
|
|
233
254
|
// Save the updated token to the database
|
|
234
255
|
await WorkspaceProjectAuthTokenService.refreshAuthToken({
|
|
@@ -685,6 +706,7 @@ class MicrosoftTeamsUtil extends WorkspaceBase {
|
|
|
685
706
|
return null;
|
|
686
707
|
}
|
|
687
708
|
static async sendMessage(data) {
|
|
709
|
+
var _a;
|
|
688
710
|
logger.debug("=== MicrosoftTeamsUtil.sendMessage called ===", {
|
|
689
711
|
projectId: data.projectId.toString(),
|
|
690
712
|
});
|
|
@@ -803,6 +825,46 @@ class MicrosoftTeamsUtil extends WorkspaceBase {
|
|
|
803
825
|
});
|
|
804
826
|
}
|
|
805
827
|
}
|
|
828
|
+
// Send to Teams chats (group / personal chats the OneUptime app was added to).
|
|
829
|
+
const chatIdsToPostTo = data.workspaceMessagePayload.chatIds || [];
|
|
830
|
+
if (chatIdsToPostTo.length > 0) {
|
|
831
|
+
logger.debug(`Processing ${chatIdsToPostTo.length} chat ids`);
|
|
832
|
+
const availableChats = await this.getChatsForProject({
|
|
833
|
+
projectId: data.projectId,
|
|
834
|
+
});
|
|
835
|
+
for (const chatId of chatIdsToPostTo) {
|
|
836
|
+
const chatAsChannel = {
|
|
837
|
+
id: chatId,
|
|
838
|
+
name: ((_a = availableChats[chatId]) === null || _a === void 0 ? void 0 : _a.name) || chatId,
|
|
839
|
+
workspaceType: WorkspaceType.MicrosoftTeams,
|
|
840
|
+
};
|
|
841
|
+
try {
|
|
842
|
+
let lastThread;
|
|
843
|
+
for (const adaptiveCard of adaptiveCards) {
|
|
844
|
+
lastThread = await this.sendAdaptiveCardToChat({
|
|
845
|
+
chatId: chatId,
|
|
846
|
+
adaptiveCard: adaptiveCard,
|
|
847
|
+
projectId: data.projectId,
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
if (lastThread) {
|
|
851
|
+
logger.debug(`Message sent successfully to chat ${chatAsChannel.name}, thread: ${JSON.stringify(lastThread)}`);
|
|
852
|
+
workspaceMessageResponse.threads.push(lastThread);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
catch (e) {
|
|
856
|
+
logger.error(`Error sending message to chat ID ${chatId}:`, {
|
|
857
|
+
projectId: data.projectId.toString(),
|
|
858
|
+
chatId: chatId,
|
|
859
|
+
});
|
|
860
|
+
logger.error(e);
|
|
861
|
+
workspaceMessageResponse.errors.push({
|
|
862
|
+
channel: chatAsChannel,
|
|
863
|
+
error: e instanceof Error ? e.message : String(e),
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
806
868
|
logger.debug("=== Message sending completed ===");
|
|
807
869
|
logger.debug(`Final thread count: ${workspaceMessageResponse.threads.length}`);
|
|
808
870
|
logger.debug(`Final response: ${JSON.stringify(workspaceMessageResponse)}`);
|
|
@@ -902,6 +964,92 @@ class MicrosoftTeamsUtil extends WorkspaceBase {
|
|
|
902
964
|
throw error;
|
|
903
965
|
}
|
|
904
966
|
}
|
|
967
|
+
/*
|
|
968
|
+
* Sends an adaptive card to a Teams group chat or personal (1:1) chat via a
|
|
969
|
+
* proactive Bot Framework message. The OneUptime app must have been added to
|
|
970
|
+
* the chat — Graph has no app-only permission for posting to chats, so the
|
|
971
|
+
* bot conversation is the only supported transport.
|
|
972
|
+
*/
|
|
973
|
+
static async sendAdaptiveCardToChat(data) {
|
|
974
|
+
var _a;
|
|
975
|
+
logger.debug("sendAdaptiveCardToChat called with data:");
|
|
976
|
+
logger.debug(`Chat ID: ${data.chatId}`);
|
|
977
|
+
logger.debug(`Project ID: ${data.projectId.toString()}`);
|
|
978
|
+
try {
|
|
979
|
+
const projectAuth = await WorkspaceProjectAuthTokenService.getProjectAuth({
|
|
980
|
+
projectId: data.projectId,
|
|
981
|
+
workspaceType: WorkspaceType.MicrosoftTeams,
|
|
982
|
+
});
|
|
983
|
+
if (!projectAuth || !projectAuth.miscData) {
|
|
984
|
+
throw new BadDataException("Microsoft Teams integration not found for this project");
|
|
985
|
+
}
|
|
986
|
+
const miscData = projectAuth.miscData;
|
|
987
|
+
if (!miscData.botId) {
|
|
988
|
+
throw new BadDataException("Bot ID not found in Microsoft Teams integration");
|
|
989
|
+
}
|
|
990
|
+
const tenantId = projectAuth.workspaceProjectId;
|
|
991
|
+
if (!tenantId) {
|
|
992
|
+
throw new BadDataException("Tenant ID not found in Microsoft Teams integration");
|
|
993
|
+
}
|
|
994
|
+
if (!MicrosoftTeamsAppClientId) {
|
|
995
|
+
throw new BadDataException("Microsoft Teams App Client ID not configured");
|
|
996
|
+
}
|
|
997
|
+
const chat = (_a = miscData.availableChats) === null || _a === void 0 ? void 0 : _a[data.chatId];
|
|
998
|
+
if (!chat) {
|
|
999
|
+
throw new BadDataException("This chat is not connected to OneUptime. Please add the OneUptime app to the chat in Microsoft Teams and try again.");
|
|
1000
|
+
}
|
|
1001
|
+
const adapter = this.getBotAdapter();
|
|
1002
|
+
const conversationReference = {
|
|
1003
|
+
bot: {
|
|
1004
|
+
id: MicrosoftTeamsAppClientId,
|
|
1005
|
+
name: "OneUptime Bot",
|
|
1006
|
+
},
|
|
1007
|
+
conversation: {
|
|
1008
|
+
id: chat.id,
|
|
1009
|
+
name: chat.name,
|
|
1010
|
+
isGroup: chat.chatType === "groupChat",
|
|
1011
|
+
conversationType: chat.chatType,
|
|
1012
|
+
tenantId: tenantId,
|
|
1013
|
+
},
|
|
1014
|
+
channelId: "msteams",
|
|
1015
|
+
/*
|
|
1016
|
+
* Fallback is the commercial-cloud global endpoint; the serviceUrl
|
|
1017
|
+
* captured from bot activities is preferred (required for GCC/DoD).
|
|
1018
|
+
*/
|
|
1019
|
+
serviceUrl: chat.serviceUrl || "https://smba.trafficmanager.net/teams/",
|
|
1020
|
+
};
|
|
1021
|
+
logger.debug(`Chat conversation reference: ${JSON.stringify(conversationReference)}`);
|
|
1022
|
+
let messageId = "";
|
|
1023
|
+
await adapter.continueConversationAsync(MicrosoftTeamsAppClientId, conversationReference, async (context) => {
|
|
1024
|
+
logger.debug("Sending adaptive card to chat as proactive message");
|
|
1025
|
+
const message = MessageFactory.attachment({
|
|
1026
|
+
contentType: "application/vnd.microsoft.card.adaptive",
|
|
1027
|
+
content: data.adaptiveCard,
|
|
1028
|
+
});
|
|
1029
|
+
const response = await context.sendActivity(message);
|
|
1030
|
+
messageId = (response === null || response === void 0 ? void 0 : response.id) || "";
|
|
1031
|
+
logger.debug(`Chat message sent with ID: ${messageId}`);
|
|
1032
|
+
});
|
|
1033
|
+
const thread = {
|
|
1034
|
+
channel: {
|
|
1035
|
+
id: chat.id,
|
|
1036
|
+
name: chat.name,
|
|
1037
|
+
workspaceType: WorkspaceType.MicrosoftTeams,
|
|
1038
|
+
},
|
|
1039
|
+
threadId: messageId,
|
|
1040
|
+
};
|
|
1041
|
+
logger.debug(`Sent message to chat via Bot Framework: ${JSON.stringify(thread)}`);
|
|
1042
|
+
return thread;
|
|
1043
|
+
}
|
|
1044
|
+
catch (error) {
|
|
1045
|
+
logger.error("Error sending adaptive card to chat via Bot Framework:", {
|
|
1046
|
+
projectId: data.projectId.toString(),
|
|
1047
|
+
chatId: data.chatId,
|
|
1048
|
+
});
|
|
1049
|
+
logger.error(error);
|
|
1050
|
+
throw error;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
905
1053
|
static async getWorkspaceChannelFromChannelId(data) {
|
|
906
1054
|
var _a;
|
|
907
1055
|
logger.debug("=== getWorkspaceChannelFromChannelId called ===", {
|
|
@@ -1243,6 +1391,25 @@ class MicrosoftTeamsUtil extends WorkspaceBase {
|
|
|
1243
1391
|
logger.debug("Message activity originates from the bot itself; ignoring to prevent a loop");
|
|
1244
1392
|
return;
|
|
1245
1393
|
}
|
|
1394
|
+
/*
|
|
1395
|
+
* Backfill chat capture from inbound messages. Chats where the app was
|
|
1396
|
+
* installed before chat capture shipped never fire install events — per
|
|
1397
|
+
* Microsoft docs, app upgrades only send installationUpdate when the
|
|
1398
|
+
* manifest's bot is added or removed, so a version bump alone re-fires
|
|
1399
|
+
* nothing. Messaging the bot in a chat is the documented recovery path,
|
|
1400
|
+
* and this also keeps the stored serviceUrl fresh (docs: verify the
|
|
1401
|
+
* stored serviceUrl when a new message arrives). Cheap when the chat is
|
|
1402
|
+
* already captured (single read, no roster fetch, no write).
|
|
1403
|
+
*/
|
|
1404
|
+
const messageConversationType = conversation["conversationType"] || "";
|
|
1405
|
+
if (messageConversationType === "personal" ||
|
|
1406
|
+
messageConversationType === "groupChat") {
|
|
1407
|
+
await this.captureChatFromBotActivity({
|
|
1408
|
+
activity: data.activity,
|
|
1409
|
+
turnContext: data.turnContext,
|
|
1410
|
+
onlyIfMissingOrStale: true,
|
|
1411
|
+
});
|
|
1412
|
+
}
|
|
1246
1413
|
// If this is actually an Adaptive Card submit wrapped as a message, route to invoke handler
|
|
1247
1414
|
if (possibleActionValue["action"] ||
|
|
1248
1415
|
((_b = possibleActionValue["data"]) === null || _b === void 0 ? void 0 : _b["action"])) {
|
|
@@ -2226,10 +2393,23 @@ All monitoring checks are passing normally.`;
|
|
|
2226
2393
|
const botWasAdded = membersAdded.some((member) => {
|
|
2227
2394
|
return member["id"] === recipientId;
|
|
2228
2395
|
});
|
|
2396
|
+
const botWasRemoved = membersRemoved.some((member) => {
|
|
2397
|
+
return member["id"] === recipientId;
|
|
2398
|
+
});
|
|
2229
2399
|
if (botWasAdded) {
|
|
2230
2400
|
logger.debug("OneUptime bot was added to a Teams conversation");
|
|
2401
|
+
await this.captureChatFromBotActivity({
|
|
2402
|
+
activity: data.activity,
|
|
2403
|
+
turnContext: data.turnContext,
|
|
2404
|
+
});
|
|
2231
2405
|
await this.sendWelcomeAdaptiveCard(data.turnContext);
|
|
2232
2406
|
}
|
|
2407
|
+
if (botWasRemoved) {
|
|
2408
|
+
logger.debug("OneUptime bot was removed from a Teams conversation");
|
|
2409
|
+
await this.removeChatFromBotActivity({
|
|
2410
|
+
activity: data.activity,
|
|
2411
|
+
});
|
|
2412
|
+
}
|
|
2233
2413
|
}
|
|
2234
2414
|
static async handleInstallationUpdateActivity(data) {
|
|
2235
2415
|
// Handle bot installation/uninstallation
|
|
@@ -2237,13 +2417,302 @@ All monitoring checks are passing normally.`;
|
|
|
2237
2417
|
const conversation = data.activity["conversation"] || {};
|
|
2238
2418
|
logger.debug(`Installation update - Action: ${action}`);
|
|
2239
2419
|
logger.debug(`Conversation: ${JSON.stringify(conversation)}`);
|
|
2240
|
-
|
|
2420
|
+
/*
|
|
2421
|
+
* Teams sends "add-upgrade" / "remove-upgrade" when an app upgrade adds
|
|
2422
|
+
* or removes the bot in the manifest (per Microsoft docs, a plain
|
|
2423
|
+
* version bump fires no installationUpdate at all). Treat them the same
|
|
2424
|
+
* as add/remove. Chats installed before chat capture shipped are
|
|
2425
|
+
* backfilled from inbound messages in handleBotMessageActivity instead.
|
|
2426
|
+
*/
|
|
2427
|
+
if (action === "add" || action === "add-upgrade") {
|
|
2241
2428
|
logger.debug("OneUptime bot was installed");
|
|
2429
|
+
await this.captureChatFromBotActivity({
|
|
2430
|
+
activity: data.activity,
|
|
2431
|
+
turnContext: data.turnContext,
|
|
2432
|
+
});
|
|
2242
2433
|
}
|
|
2243
|
-
else if (action === "remove") {
|
|
2434
|
+
else if (action === "remove" || action === "remove-upgrade") {
|
|
2244
2435
|
logger.debug("OneUptime bot was uninstalled");
|
|
2436
|
+
await this.removeChatFromBotActivity({
|
|
2437
|
+
activity: data.activity,
|
|
2438
|
+
});
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
/*
|
|
2442
|
+
* Chats (group chats and personal 1:1 chats) cannot be listed with the
|
|
2443
|
+
* app-only Graph token, so the only way OneUptime learns about them is by
|
|
2444
|
+
* capturing the conversation details when the OneUptime app is added to a
|
|
2445
|
+
* chat. These captured chats power the "post to chat" notification rules.
|
|
2446
|
+
*/
|
|
2447
|
+
static getChatTypeFromConversation(conversation) {
|
|
2448
|
+
const conversationType = conversation["conversationType"] || "";
|
|
2449
|
+
if (conversationType === "personal" || conversationType === "groupChat") {
|
|
2450
|
+
return conversationType;
|
|
2451
|
+
}
|
|
2452
|
+
return null; // channels and meetings are not chats.
|
|
2453
|
+
}
|
|
2454
|
+
static getChatDisplayName(data) {
|
|
2455
|
+
/*
|
|
2456
|
+
* Keep well under the 100-char ShortText columns that store the chat
|
|
2457
|
+
* name in notification logs — Teams chat topics can be much longer.
|
|
2458
|
+
*/
|
|
2459
|
+
const maxNameLength = 80;
|
|
2460
|
+
const truncate = (name) => {
|
|
2461
|
+
return name.length > maxNameLength
|
|
2462
|
+
? `${name.substring(0, maxNameLength - 1)}…`
|
|
2463
|
+
: name;
|
|
2464
|
+
};
|
|
2465
|
+
if (data.topic && data.topic.trim()) {
|
|
2466
|
+
return truncate(data.topic.trim());
|
|
2467
|
+
}
|
|
2468
|
+
const memberNames = data.memberNames.filter((name) => {
|
|
2469
|
+
return Boolean(name && name.trim());
|
|
2470
|
+
});
|
|
2471
|
+
if (data.chatType === "personal") {
|
|
2472
|
+
return memberNames[0] ? truncate(`${memberNames[0]}`) : "Personal chat";
|
|
2473
|
+
}
|
|
2474
|
+
if (memberNames.length === 0) {
|
|
2475
|
+
return "Group chat";
|
|
2476
|
+
}
|
|
2477
|
+
const maxNamesToShow = 3;
|
|
2478
|
+
const shownNames = memberNames.slice(0, maxNamesToShow);
|
|
2479
|
+
const remainingCount = memberNames.length - shownNames.length;
|
|
2480
|
+
if (remainingCount > 0) {
|
|
2481
|
+
return truncate(`${shownNames.join(", ")} + ${remainingCount} more`);
|
|
2482
|
+
}
|
|
2483
|
+
return truncate(shownNames.join(", "));
|
|
2484
|
+
}
|
|
2485
|
+
/*
|
|
2486
|
+
* Returns true when every connected project of this tenant already has
|
|
2487
|
+
* this chat stored with the same service URL — i.e. there is nothing to
|
|
2488
|
+
* capture or refresh.
|
|
2489
|
+
*/
|
|
2490
|
+
static async isChatCapturedForTenant(data) {
|
|
2491
|
+
var _a, _b;
|
|
2492
|
+
const projectAuths = await WorkspaceProjectAuthTokenService.findBy({
|
|
2493
|
+
query: {
|
|
2494
|
+
workspaceType: WorkspaceType.MicrosoftTeams,
|
|
2495
|
+
workspaceProjectId: data.tenantId,
|
|
2496
|
+
},
|
|
2497
|
+
select: {
|
|
2498
|
+
_id: true,
|
|
2499
|
+
miscData: true,
|
|
2500
|
+
},
|
|
2501
|
+
limit: LIMIT_MAX,
|
|
2502
|
+
skip: 0,
|
|
2503
|
+
props: {
|
|
2504
|
+
isRoot: true,
|
|
2505
|
+
},
|
|
2506
|
+
});
|
|
2507
|
+
if (projectAuths.length === 0) {
|
|
2508
|
+
return true; // no connected projects — nothing to capture into.
|
|
2509
|
+
}
|
|
2510
|
+
for (const projectAuth of projectAuths) {
|
|
2511
|
+
const chat = (_b = (_a = projectAuth.miscData) === null || _a === void 0 ? void 0 : _a.availableChats) === null || _b === void 0 ? void 0 : _b[data.chatId];
|
|
2512
|
+
if (!chat) {
|
|
2513
|
+
return false;
|
|
2514
|
+
}
|
|
2515
|
+
if (data.serviceUrl && chat.serviceUrl !== data.serviceUrl) {
|
|
2516
|
+
return false; // stored serviceUrl is stale.
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
return true;
|
|
2520
|
+
}
|
|
2521
|
+
static async captureChatFromBotActivity(data) {
|
|
2522
|
+
var _a, _b;
|
|
2523
|
+
try {
|
|
2524
|
+
const conversation = data.activity["conversation"] || {};
|
|
2525
|
+
const chatType = this.getChatTypeFromConversation(conversation);
|
|
2526
|
+
if (!chatType) {
|
|
2527
|
+
return; // bot was added to a team channel, not a chat.
|
|
2528
|
+
}
|
|
2529
|
+
const chatId = conversation["id"] || "";
|
|
2530
|
+
if (!chatId) {
|
|
2531
|
+
logger.debug("No conversation id found on chat activity. Skipping.");
|
|
2532
|
+
return;
|
|
2533
|
+
}
|
|
2534
|
+
const channelData = data.activity["channelData"] || {};
|
|
2535
|
+
const tenantId = ((_a = channelData["tenant"]) === null || _a === void 0 ? void 0 : _a["id"]) ||
|
|
2536
|
+
conversation["tenantId"] ||
|
|
2537
|
+
"";
|
|
2538
|
+
if (!tenantId) {
|
|
2539
|
+
logger.debug("No tenant id found on chat activity. Skipping.");
|
|
2540
|
+
return;
|
|
2541
|
+
}
|
|
2542
|
+
const activityServiceUrl = data.activity["serviceUrl"] ||
|
|
2543
|
+
data.turnContext.activity.serviceUrl ||
|
|
2544
|
+
undefined;
|
|
2545
|
+
/*
|
|
2546
|
+
* On the message-backfill path, skip the roster fetch and DB writes
|
|
2547
|
+
* when the chat is already captured with a fresh serviceUrl.
|
|
2548
|
+
*/
|
|
2549
|
+
if (data.onlyIfMissingOrStale) {
|
|
2550
|
+
const alreadyCaptured = await this.isChatCapturedForTenant({
|
|
2551
|
+
tenantId: tenantId,
|
|
2552
|
+
chatId: chatId,
|
|
2553
|
+
serviceUrl: activityServiceUrl,
|
|
2554
|
+
});
|
|
2555
|
+
if (alreadyCaptured) {
|
|
2556
|
+
return;
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
// Resolve a human friendly name for the chat.
|
|
2560
|
+
const topic = conversation["name"];
|
|
2561
|
+
let memberNames = [];
|
|
2562
|
+
try {
|
|
2563
|
+
const botId = (_b = data.turnContext.activity.recipient) === null || _b === void 0 ? void 0 : _b.id;
|
|
2564
|
+
/*
|
|
2565
|
+
* TeamsInfo.getMembers is deprecated — page through the roster
|
|
2566
|
+
* instead. Chats return the full roster in one page in practice.
|
|
2567
|
+
*/
|
|
2568
|
+
const members = [];
|
|
2569
|
+
let continuationToken = undefined;
|
|
2570
|
+
do {
|
|
2571
|
+
const page = await TeamsInfo.getPagedMembers(data.turnContext, 500, continuationToken);
|
|
2572
|
+
members.push(...(page.members || []));
|
|
2573
|
+
continuationToken = page.continuationToken;
|
|
2574
|
+
} while (continuationToken);
|
|
2575
|
+
memberNames = members
|
|
2576
|
+
.filter((member) => {
|
|
2577
|
+
return member.id !== botId;
|
|
2578
|
+
})
|
|
2579
|
+
.map((member) => {
|
|
2580
|
+
return member.name || "";
|
|
2581
|
+
});
|
|
2582
|
+
}
|
|
2583
|
+
catch (err) {
|
|
2584
|
+
logger.debug("Could not fetch chat members for chat name resolution");
|
|
2585
|
+
logger.debug(err);
|
|
2586
|
+
}
|
|
2587
|
+
const chat = {
|
|
2588
|
+
id: chatId,
|
|
2589
|
+
name: this.getChatDisplayName({
|
|
2590
|
+
chatType: chatType,
|
|
2591
|
+
topic: topic,
|
|
2592
|
+
memberNames: memberNames,
|
|
2593
|
+
}),
|
|
2594
|
+
chatType: chatType,
|
|
2595
|
+
serviceUrl: activityServiceUrl,
|
|
2596
|
+
addedAt: OneUptimeDate.getCurrentDate().toISOString(),
|
|
2597
|
+
};
|
|
2598
|
+
await this.saveChatToProjectAuthTokens({
|
|
2599
|
+
tenantId: tenantId,
|
|
2600
|
+
chat: chat,
|
|
2601
|
+
});
|
|
2602
|
+
logger.debug(`Captured Microsoft Teams chat ${chatId} (${chat.name}) for tenant ${tenantId}`);
|
|
2603
|
+
}
|
|
2604
|
+
catch (err) {
|
|
2605
|
+
logger.error("Error capturing Microsoft Teams chat from bot activity:");
|
|
2606
|
+
logger.error(err);
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
static async removeChatFromBotActivity(data) {
|
|
2610
|
+
var _a;
|
|
2611
|
+
try {
|
|
2612
|
+
const conversation = data.activity["conversation"] || {};
|
|
2613
|
+
const chatType = this.getChatTypeFromConversation(conversation);
|
|
2614
|
+
if (!chatType) {
|
|
2615
|
+
return;
|
|
2616
|
+
}
|
|
2617
|
+
const chatId = conversation["id"] || "";
|
|
2618
|
+
const channelData = data.activity["channelData"] || {};
|
|
2619
|
+
const tenantId = ((_a = channelData["tenant"]) === null || _a === void 0 ? void 0 : _a["id"]) ||
|
|
2620
|
+
conversation["tenantId"] ||
|
|
2621
|
+
"";
|
|
2622
|
+
if (!chatId || !tenantId) {
|
|
2623
|
+
return;
|
|
2624
|
+
}
|
|
2625
|
+
await this.removeChatFromProjectAuthTokens({
|
|
2626
|
+
tenantId: tenantId,
|
|
2627
|
+
chatId: chatId,
|
|
2628
|
+
});
|
|
2629
|
+
logger.debug(`Removed Microsoft Teams chat ${chatId} for tenant ${tenantId}`);
|
|
2630
|
+
}
|
|
2631
|
+
catch (err) {
|
|
2632
|
+
logger.error("Error removing Microsoft Teams chat from bot activity:");
|
|
2633
|
+
logger.error(err);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
static async saveChatToProjectAuthTokens(data) {
|
|
2637
|
+
/*
|
|
2638
|
+
* A tenant can be connected to more than one OneUptime project, and the
|
|
2639
|
+
* install event does not say which project it belongs to — so save the
|
|
2640
|
+
* chat on every project connected to this tenant.
|
|
2641
|
+
*/
|
|
2642
|
+
const projectAuths = await WorkspaceProjectAuthTokenService.findBy({
|
|
2643
|
+
query: {
|
|
2644
|
+
workspaceType: WorkspaceType.MicrosoftTeams,
|
|
2645
|
+
workspaceProjectId: data.tenantId,
|
|
2646
|
+
},
|
|
2647
|
+
select: {
|
|
2648
|
+
_id: true,
|
|
2649
|
+
miscData: true,
|
|
2650
|
+
},
|
|
2651
|
+
limit: LIMIT_MAX,
|
|
2652
|
+
skip: 0,
|
|
2653
|
+
props: {
|
|
2654
|
+
isRoot: true,
|
|
2655
|
+
},
|
|
2656
|
+
});
|
|
2657
|
+
for (const projectAuth of projectAuths) {
|
|
2658
|
+
const miscData = Object.assign({}, (projectAuth.miscData || {}));
|
|
2659
|
+
miscData.availableChats = Object.assign(Object.assign({}, (miscData.availableChats || {})), { [data.chat.id]: data.chat });
|
|
2660
|
+
await WorkspaceProjectAuthTokenService.updateOneById({
|
|
2661
|
+
id: projectAuth.id,
|
|
2662
|
+
data: {
|
|
2663
|
+
miscData: miscData,
|
|
2664
|
+
},
|
|
2665
|
+
props: {
|
|
2666
|
+
isRoot: true,
|
|
2667
|
+
},
|
|
2668
|
+
});
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
static async removeChatFromProjectAuthTokens(data) {
|
|
2672
|
+
const projectAuths = await WorkspaceProjectAuthTokenService.findBy({
|
|
2673
|
+
query: {
|
|
2674
|
+
workspaceType: WorkspaceType.MicrosoftTeams,
|
|
2675
|
+
workspaceProjectId: data.tenantId,
|
|
2676
|
+
},
|
|
2677
|
+
select: {
|
|
2678
|
+
_id: true,
|
|
2679
|
+
miscData: true,
|
|
2680
|
+
},
|
|
2681
|
+
limit: LIMIT_MAX,
|
|
2682
|
+
skip: 0,
|
|
2683
|
+
props: {
|
|
2684
|
+
isRoot: true,
|
|
2685
|
+
},
|
|
2686
|
+
});
|
|
2687
|
+
for (const projectAuth of projectAuths) {
|
|
2688
|
+
const miscData = Object.assign({}, (projectAuth.miscData || {}));
|
|
2689
|
+
if (!miscData.availableChats || !miscData.availableChats[data.chatId]) {
|
|
2690
|
+
continue;
|
|
2691
|
+
}
|
|
2692
|
+
const availableChats = Object.assign({}, miscData.availableChats);
|
|
2693
|
+
delete availableChats[data.chatId];
|
|
2694
|
+
miscData.availableChats = availableChats;
|
|
2695
|
+
await WorkspaceProjectAuthTokenService.updateOneById({
|
|
2696
|
+
id: projectAuth.id,
|
|
2697
|
+
data: {
|
|
2698
|
+
miscData: miscData,
|
|
2699
|
+
},
|
|
2700
|
+
props: {
|
|
2701
|
+
isRoot: true,
|
|
2702
|
+
},
|
|
2703
|
+
});
|
|
2245
2704
|
}
|
|
2246
2705
|
}
|
|
2706
|
+
static async getChatsForProject(data) {
|
|
2707
|
+
const projectAuth = await WorkspaceProjectAuthTokenService.getProjectAuth({
|
|
2708
|
+
projectId: data.projectId,
|
|
2709
|
+
workspaceType: WorkspaceType.MicrosoftTeams,
|
|
2710
|
+
});
|
|
2711
|
+
if (!projectAuth || !projectAuth.miscData) {
|
|
2712
|
+
return {};
|
|
2713
|
+
}
|
|
2714
|
+
return (projectAuth.miscData.availableChats || {});
|
|
2715
|
+
}
|
|
2247
2716
|
/**
|
|
2248
2717
|
* Process Bot Framework activity using the botbuilder SDK adapter.processActivity
|
|
2249
2718
|
* This replaces the manual JWT validation and activity handling with proper SDK methods
|
|
@@ -2290,6 +2759,15 @@ All monitoring checks are passing normally.`;
|
|
|
2290
2759
|
});
|
|
2291
2760
|
await next();
|
|
2292
2761
|
});
|
|
2762
|
+
this.onMembersRemoved(async (context, next) => {
|
|
2763
|
+
logger.debug("Handling members removed activity: " +
|
|
2764
|
+
JSON.stringify(context.activity));
|
|
2765
|
+
await MicrosoftTeamsUtil.handleConversationUpdateActivity({
|
|
2766
|
+
activity: context.activity,
|
|
2767
|
+
turnContext: context,
|
|
2768
|
+
});
|
|
2769
|
+
await next();
|
|
2770
|
+
});
|
|
2293
2771
|
this.onInstallationUpdateAdd(async (context, next) => {
|
|
2294
2772
|
logger.debug("Handling installation update add activity: " +
|
|
2295
2773
|
JSON.stringify(context.activity));
|
|
@@ -2299,6 +2777,15 @@ All monitoring checks are passing normally.`;
|
|
|
2299
2777
|
});
|
|
2300
2778
|
await next();
|
|
2301
2779
|
});
|
|
2780
|
+
this.onInstallationUpdateRemove(async (context, next) => {
|
|
2781
|
+
logger.debug("Handling installation update remove activity: " +
|
|
2782
|
+
JSON.stringify(context.activity));
|
|
2783
|
+
await MicrosoftTeamsUtil.handleInstallationUpdateActivity({
|
|
2784
|
+
activity: context.activity,
|
|
2785
|
+
turnContext: context,
|
|
2786
|
+
});
|
|
2787
|
+
await next();
|
|
2788
|
+
});
|
|
2302
2789
|
}
|
|
2303
2790
|
async onInvokeActivity(context) {
|
|
2304
2791
|
logger.debug("Handling invoke activity: " + JSON.stringify(context.activity));
|
|
@@ -2562,8 +3049,27 @@ All monitoring checks are passing normally.`;
|
|
|
2562
3049
|
return acc;
|
|
2563
3050
|
}, {});
|
|
2564
3051
|
logger.debug(`Processed ${Object.keys(availableTeams).length} teams`);
|
|
2565
|
-
|
|
2566
|
-
|
|
3052
|
+
/*
|
|
3053
|
+
* Update project auth token with new teams. Re-read miscData first —
|
|
3054
|
+
* the snapshot from the start of this method is stale by the length
|
|
3055
|
+
* of the paginated Graph fetch, and writing it back verbatim would
|
|
3056
|
+
* erase concurrent updates (e.g. chats captured into availableChats
|
|
3057
|
+
* by bot install events, which cannot be re-derived).
|
|
3058
|
+
*/
|
|
3059
|
+
let miscData = projectAuth.miscData || {};
|
|
3060
|
+
try {
|
|
3061
|
+
const latestProjectAuth = await WorkspaceProjectAuthTokenService.getProjectAuth({
|
|
3062
|
+
projectId: data.projectId,
|
|
3063
|
+
workspaceType: WorkspaceType.MicrosoftTeams,
|
|
3064
|
+
});
|
|
3065
|
+
if (latestProjectAuth === null || latestProjectAuth === void 0 ? void 0 : latestProjectAuth.miscData) {
|
|
3066
|
+
miscData = latestProjectAuth.miscData;
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
3069
|
+
catch (err) {
|
|
3070
|
+
logger.debug("Could not re-read miscData before teams refresh write");
|
|
3071
|
+
logger.debug(err);
|
|
3072
|
+
}
|
|
2567
3073
|
miscData.availableTeams = availableTeams;
|
|
2568
3074
|
miscData.tenantId = tenantId;
|
|
2569
3075
|
await WorkspaceProjectAuthTokenService.updateOneById({
|
|
@@ -2818,6 +3324,12 @@ __decorate([
|
|
|
2818
3324
|
__metadata("design:paramtypes", [Object]),
|
|
2819
3325
|
__metadata("design:returntype", Promise)
|
|
2820
3326
|
], MicrosoftTeamsUtil, "sendAdaptiveCardToChannel", null);
|
|
3327
|
+
__decorate([
|
|
3328
|
+
CaptureSpan(),
|
|
3329
|
+
__metadata("design:type", Function),
|
|
3330
|
+
__metadata("design:paramtypes", [Object]),
|
|
3331
|
+
__metadata("design:returntype", Promise)
|
|
3332
|
+
], MicrosoftTeamsUtil, "sendAdaptiveCardToChat", null);
|
|
2821
3333
|
__decorate([
|
|
2822
3334
|
CaptureSpan(),
|
|
2823
3335
|
__metadata("design:type", Function),
|
|
@@ -2998,6 +3510,36 @@ __decorate([
|
|
|
2998
3510
|
__metadata("design:paramtypes", [Object]),
|
|
2999
3511
|
__metadata("design:returntype", Promise)
|
|
3000
3512
|
], MicrosoftTeamsUtil, "handleInstallationUpdateActivity", null);
|
|
3513
|
+
__decorate([
|
|
3514
|
+
CaptureSpan(),
|
|
3515
|
+
__metadata("design:type", Function),
|
|
3516
|
+
__metadata("design:paramtypes", [Object]),
|
|
3517
|
+
__metadata("design:returntype", Promise)
|
|
3518
|
+
], MicrosoftTeamsUtil, "captureChatFromBotActivity", null);
|
|
3519
|
+
__decorate([
|
|
3520
|
+
CaptureSpan(),
|
|
3521
|
+
__metadata("design:type", Function),
|
|
3522
|
+
__metadata("design:paramtypes", [Object]),
|
|
3523
|
+
__metadata("design:returntype", Promise)
|
|
3524
|
+
], MicrosoftTeamsUtil, "removeChatFromBotActivity", null);
|
|
3525
|
+
__decorate([
|
|
3526
|
+
CaptureSpan(),
|
|
3527
|
+
__metadata("design:type", Function),
|
|
3528
|
+
__metadata("design:paramtypes", [Object]),
|
|
3529
|
+
__metadata("design:returntype", Promise)
|
|
3530
|
+
], MicrosoftTeamsUtil, "saveChatToProjectAuthTokens", null);
|
|
3531
|
+
__decorate([
|
|
3532
|
+
CaptureSpan(),
|
|
3533
|
+
__metadata("design:type", Function),
|
|
3534
|
+
__metadata("design:paramtypes", [Object]),
|
|
3535
|
+
__metadata("design:returntype", Promise)
|
|
3536
|
+
], MicrosoftTeamsUtil, "removeChatFromProjectAuthTokens", null);
|
|
3537
|
+
__decorate([
|
|
3538
|
+
CaptureSpan(),
|
|
3539
|
+
__metadata("design:type", Function),
|
|
3540
|
+
__metadata("design:paramtypes", [Object]),
|
|
3541
|
+
__metadata("design:returntype", Promise)
|
|
3542
|
+
], MicrosoftTeamsUtil, "getChatsForProject", null);
|
|
3001
3543
|
__decorate([
|
|
3002
3544
|
CaptureSpan(),
|
|
3003
3545
|
__metadata("design:type", Function),
|