@checkfirst/nestjs-outlook 2.0.0 → 3.0.0
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/README.md +160 -20
- package/dist/controllers/calendar.controller.d.ts +10 -0
- package/dist/controllers/calendar.controller.js +166 -0
- package/dist/controllers/calendar.controller.js.map +1 -0
- package/dist/controllers/email.controller.d.ts +10 -0
- package/dist/controllers/email.controller.js +166 -0
- package/dist/controllers/email.controller.js.map +1 -0
- package/dist/controllers/microsoft-auth.controller.d.ts +1 -1
- package/dist/controllers/microsoft-auth.controller.js +1 -1
- package/dist/controllers/microsoft-auth.controller.js.map +1 -1
- package/dist/dto/outlook-webhook-notification.dto.d.ts +5 -0
- package/dist/dto/outlook-webhook-notification.dto.js +39 -1
- package/dist/dto/outlook-webhook-notification.dto.js.map +1 -1
- package/dist/entities/outlook-webhook-subscription.entity.js +3 -4
- package/dist/entities/outlook-webhook-subscription.entity.js.map +1 -1
- package/dist/event-types.enum.d.ts +4 -1
- package/dist/event-types.enum.js +3 -0
- package/dist/event-types.enum.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/microsoft-outlook.module.js +9 -6
- package/dist/microsoft-outlook.module.js.map +1 -1
- package/dist/migrations/1697025846000-CreateOutlookTables.js +2 -1
- package/dist/migrations/1697025846000-CreateOutlookTables.js.map +1 -1
- package/dist/migrations/1697026000000-EnsureUniqueSubscriptions.d.ts +5 -0
- package/dist/migrations/1697026000000-EnsureUniqueSubscriptions.js +27 -0
- package/dist/migrations/1697026000000-EnsureUniqueSubscriptions.js.map +1 -0
- package/dist/repositories/outlook-webhook-subscription.repository.js +14 -1
- package/dist/repositories/outlook-webhook-subscription.repository.js.map +1 -1
- package/dist/services/auth/index.d.ts +1 -0
- package/dist/services/auth/index.js +18 -0
- package/dist/services/auth/index.js.map +1 -0
- package/dist/services/{microsoft-auth.service.d.ts → auth/microsoft-auth.service.d.ts} +11 -7
- package/dist/services/{microsoft-auth.service.js → auth/microsoft-auth.service.js} +56 -27
- package/dist/services/auth/microsoft-auth.service.js.map +1 -0
- package/dist/services/{outlook.service.d.ts → calendar/calendar.service.d.ts} +6 -6
- package/dist/services/{outlook.service.js → calendar/calendar.service.js} +96 -66
- package/dist/services/calendar/calendar.service.js.map +1 -0
- package/dist/services/calendar/index.d.ts +1 -0
- package/dist/services/calendar/index.js +18 -0
- package/dist/services/calendar/index.js.map +1 -0
- package/dist/services/email/email.service.d.ts +24 -0
- package/dist/services/email/email.service.js +207 -0
- package/dist/services/email/email.service.js.map +1 -0
- package/dist/services/email/index.d.ts +1 -0
- package/dist/services/email/index.js +18 -0
- package/dist/services/email/index.js.map +1 -0
- package/dist/services/index.d.ts +3 -0
- package/dist/services/index.js +20 -0
- package/dist/services/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/microsoft-graph.types.d.ts +1 -1
- package/package.json +6 -2
- package/dist/controllers/outlook.controller.d.ts +0 -8
- package/dist/controllers/outlook.controller.js +0 -117
- package/dist/controllers/outlook.controller.js.map +0 -1
- package/dist/services/microsoft-auth.service.js.map +0 -1
- package/dist/services/outlook.service.js.map +0 -1
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ An opinionated NestJS module for Microsoft Outlook integration that provides eas
|
|
|
18
18
|
|
|
19
19
|
- 🔄 Simplified Microsoft OAuth flow
|
|
20
20
|
- 📅 Calendar events management
|
|
21
|
+
- 📧 Email sending capabilities
|
|
21
22
|
- 🔔 Real-time webhooks for changes
|
|
22
23
|
- 🔐 Secure token storage and refresh
|
|
23
24
|
|
|
@@ -79,7 +80,20 @@ export class CreateOutlookTables1697025846000 implements MigrationInterface {
|
|
|
79
80
|
|
|
80
81
|
You can customize this migration to match your database dialect (PostgreSQL, MySQL, etc.) if needed.
|
|
81
82
|
|
|
82
|
-
### 2.
|
|
83
|
+
### 2. Microsoft App Registration
|
|
84
|
+
|
|
85
|
+
Register your application in the Azure Portal to get a client ID and secret:
|
|
86
|
+
|
|
87
|
+
1. Go to the [Azure Portal](https://portal.azure.com/)
|
|
88
|
+
2. Navigate to Azure Active Directory > App registrations
|
|
89
|
+
3. Create a new registration
|
|
90
|
+
4. Configure redirects to include your callback URL
|
|
91
|
+
5. Add the following Microsoft Graph API permissions:
|
|
92
|
+
- `Calendars.ReadWrite` - For calendar operations
|
|
93
|
+
- `Mail.Send` - For sending emails
|
|
94
|
+
- `offline_access` - For refresh tokens
|
|
95
|
+
|
|
96
|
+
### 3. Import Required Modules
|
|
83
97
|
|
|
84
98
|
Register the module in your NestJS application and include the module entities in TypeORM:
|
|
85
99
|
|
|
@@ -122,34 +136,119 @@ const outlookPackagePath = path.dirname(require.resolve('@checkfirst/nestjs-outl
|
|
|
122
136
|
export class AppModule {}
|
|
123
137
|
```
|
|
124
138
|
|
|
125
|
-
###
|
|
139
|
+
### 4. Create an Auth Controller
|
|
126
140
|
|
|
127
|
-
|
|
141
|
+
The library provides a MicrosoftAuthController for handling authentication, but you can also create your own:
|
|
128
142
|
|
|
129
143
|
```typescript
|
|
130
|
-
|
|
144
|
+
import { Controller, Get, Req } from '@nestjs/common';
|
|
145
|
+
import { MicrosoftAuthService } from '@checkfirst/nestjs-outlook';
|
|
146
|
+
|
|
147
|
+
@Controller('auth')
|
|
148
|
+
export class AuthController {
|
|
131
149
|
constructor(
|
|
132
150
|
private readonly microsoftAuthService: MicrosoftAuthService
|
|
133
151
|
) {}
|
|
134
152
|
|
|
135
|
-
@
|
|
136
|
-
@
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
if (!user?.id) {
|
|
140
|
-
throw new ForbiddenException('User not authenticated');
|
|
141
|
-
}
|
|
153
|
+
@Get('microsoft/login')
|
|
154
|
+
async login(@Req() req: any) {
|
|
155
|
+
// In a real application, get the user ID from your authentication system
|
|
156
|
+
const userId = req.user?.id.toString() || '1';
|
|
142
157
|
|
|
143
158
|
// Get the login URL from the Microsoft auth service
|
|
144
|
-
return await this.microsoftAuthService.getLoginUrl(
|
|
159
|
+
return await this.microsoftAuthService.getLoginUrl(userId);
|
|
145
160
|
}
|
|
146
161
|
}
|
|
147
162
|
```
|
|
148
163
|
|
|
149
|
-
## Available Services
|
|
164
|
+
## Available Services and Controllers
|
|
165
|
+
|
|
166
|
+
The library provides specialized services and controllers for Microsoft Graph API operations:
|
|
167
|
+
|
|
168
|
+
### 1. MicrosoftAuthService and MicrosoftAuthController
|
|
169
|
+
|
|
170
|
+
Handle authentication, token management, and OAuth flow:
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// Initiate the OAuth flow - redirects user to Microsoft login
|
|
174
|
+
const loginUrl = await microsoftAuthService.getLoginUrl(userId);
|
|
175
|
+
|
|
176
|
+
// Exchange OAuth code for tokens (used in callback endpoint)
|
|
177
|
+
const tokens = await microsoftAuthService.exchangeCodeForToken(code, state);
|
|
178
|
+
|
|
179
|
+
// Refresh an expired access token
|
|
180
|
+
const newTokens = await microsoftAuthService.refreshAccessToken(refreshToken, userId);
|
|
181
|
+
|
|
182
|
+
// Check if a token is expired
|
|
183
|
+
const isExpired = microsoftAuthService.isTokenExpired(tokenExpiryDate);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 2. CalendarService and CalendarController
|
|
187
|
+
|
|
188
|
+
Manage calendar operations with Microsoft Graph API:
|
|
150
189
|
|
|
151
|
-
|
|
152
|
-
|
|
190
|
+
```typescript
|
|
191
|
+
// Create a calendar event
|
|
192
|
+
const event = {
|
|
193
|
+
subject: 'Team Meeting',
|
|
194
|
+
start: {
|
|
195
|
+
dateTime: '2023-06-01T10:00:00',
|
|
196
|
+
timeZone: 'UTC',
|
|
197
|
+
},
|
|
198
|
+
end: {
|
|
199
|
+
dateTime: '2023-06-01T11:00:00',
|
|
200
|
+
timeZone: 'UTC',
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const result = await calendarService.createEvent(
|
|
205
|
+
event,
|
|
206
|
+
accessToken,
|
|
207
|
+
refreshToken,
|
|
208
|
+
tokenExpiry,
|
|
209
|
+
userId,
|
|
210
|
+
calendarId
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
// Get user's default calendar ID
|
|
214
|
+
const calendarId = await calendarService.getDefaultCalendarId(accessToken);
|
|
215
|
+
|
|
216
|
+
// Create webhook subscription for calendar events
|
|
217
|
+
await calendarService.createWebhookSubscription(userId, accessToken, refreshToken);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
The CalendarController provides a webhook endpoint at `/calendar/webhook` for receiving notifications from Microsoft Graph about calendar changes.
|
|
221
|
+
|
|
222
|
+
### 3. EmailService
|
|
223
|
+
|
|
224
|
+
Provides email sending capabilities via Microsoft Graph API:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
// Create email message
|
|
228
|
+
const message = {
|
|
229
|
+
subject: 'Hello from NestJS Outlook',
|
|
230
|
+
body: {
|
|
231
|
+
contentType: 'HTML',
|
|
232
|
+
content: '<p>This is the email body</p>'
|
|
233
|
+
},
|
|
234
|
+
toRecipients: [
|
|
235
|
+
{
|
|
236
|
+
emailAddress: {
|
|
237
|
+
address: 'recipient@example.com'
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
// Send the email
|
|
244
|
+
const result = await emailService.sendEmail(
|
|
245
|
+
message,
|
|
246
|
+
accessToken,
|
|
247
|
+
refreshToken,
|
|
248
|
+
tokenExpiry,
|
|
249
|
+
userId
|
|
250
|
+
);
|
|
251
|
+
```
|
|
153
252
|
|
|
154
253
|
## Events
|
|
155
254
|
|
|
@@ -172,31 +271,72 @@ You can listen to these events in your application using the `@OnEvent` decorato
|
|
|
172
271
|
```typescript
|
|
173
272
|
import { Injectable } from '@nestjs/common';
|
|
174
273
|
import { OnEvent } from '@nestjs/event-emitter';
|
|
175
|
-
import { OutlookEventTypes, OutlookResourceData } from '@checkfirst/nestjs-outlook';
|
|
274
|
+
import { OutlookEventTypes, OutlookResourceData, TokenResponse } from '@checkfirst/nestjs-outlook';
|
|
176
275
|
|
|
177
276
|
@Injectable()
|
|
178
277
|
export class YourService {
|
|
278
|
+
// Handle token save event
|
|
279
|
+
@OnEvent(OutlookEventTypes.AUTH_TOKENS_SAVE)
|
|
280
|
+
async handleAuthTokensSave(userId: string, tokenData: TokenResponse) {
|
|
281
|
+
console.log(`Saving new tokens for user ${userId}`);
|
|
282
|
+
// Save tokens to your database
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Handle calendar events
|
|
179
286
|
@OnEvent(OutlookEventTypes.EVENT_CREATED)
|
|
180
287
|
handleOutlookEventCreated(data: OutlookResourceData) {
|
|
181
288
|
console.log('New Outlook event created:', data.id);
|
|
182
|
-
// Handle the new event
|
|
289
|
+
// Handle the new event
|
|
183
290
|
}
|
|
184
291
|
|
|
185
292
|
@OnEvent(OutlookEventTypes.EVENT_UPDATED)
|
|
186
293
|
handleOutlookEventUpdated(data: OutlookResourceData) {
|
|
187
294
|
console.log('Outlook event updated:', data.id);
|
|
188
|
-
// Handle the updated event
|
|
295
|
+
// Handle the updated event
|
|
189
296
|
}
|
|
190
297
|
|
|
191
298
|
@OnEvent(OutlookEventTypes.EVENT_DELETED)
|
|
192
299
|
handleOutlookEventDeleted(data: OutlookResourceData) {
|
|
193
300
|
console.log('Outlook event deleted:', data.id);
|
|
194
|
-
// Handle the deleted event
|
|
301
|
+
// Handle the deleted event
|
|
195
302
|
}
|
|
196
303
|
}
|
|
197
304
|
```
|
|
198
305
|
|
|
199
|
-
|
|
306
|
+
## Example Application Architecture
|
|
307
|
+
|
|
308
|
+
For a more complete example of how to structure your application using this library, check out the sample application included in this repository:
|
|
309
|
+
|
|
310
|
+
**Path:** `samples/nestjs-outlook-example/`
|
|
311
|
+
|
|
312
|
+
The sample app demonstrates a modular architecture with clear separation of concerns:
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
src/
|
|
316
|
+
├── auth/
|
|
317
|
+
│ ├── auth.controller.ts # Handles Microsoft login and OAuth callback
|
|
318
|
+
│ └── auth.module.ts # Configures MicrosoftOutlookModule for auth
|
|
319
|
+
│
|
|
320
|
+
├── calendar/
|
|
321
|
+
│ ├── calendar.controller.ts # API endpoints for calendar operations
|
|
322
|
+
│ ├── calendar.module.ts # Configures MicrosoftOutlookModule for calendar
|
|
323
|
+
│ ├── calendar.service.ts # Your business logic for calendars
|
|
324
|
+
│ └── dto/
|
|
325
|
+
│ └── create-event.dto.ts # Data validation for event creation
|
|
326
|
+
│
|
|
327
|
+
├── email/
|
|
328
|
+
│ ├── email.controller.ts # API endpoints for email operations
|
|
329
|
+
│ ├── email.module.ts # Configures MicrosoftOutlookModule for email
|
|
330
|
+
│ ├── email.service.ts # Your business logic for emails
|
|
331
|
+
│ └── dto/
|
|
332
|
+
│ └── send-email.dto.ts # Data validation for email sending
|
|
333
|
+
│
|
|
334
|
+
└── app.module.ts # Root module that imports feature modules
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
> **See:** [`samples/nestjs-outlook-example`](./samples/nestjs-outlook-example) for a full working example.
|
|
338
|
+
|
|
339
|
+
This modular architecture keeps concerns separated and makes your application easier to maintain and test.
|
|
200
340
|
|
|
201
341
|
## Support
|
|
202
342
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Response, Request } from 'express';
|
|
2
|
+
import { CalendarService } from '../services/calendar/calendar.service';
|
|
3
|
+
import { OutlookWebhookNotificationDto } from '../dto/outlook-webhook-notification.dto';
|
|
4
|
+
export declare class CalendarController {
|
|
5
|
+
private readonly calendarService;
|
|
6
|
+
private readonly logger;
|
|
7
|
+
constructor(calendarService: CalendarService);
|
|
8
|
+
handleCalendarWebhook(validationToken: string, notificationBody: OutlookWebhookNotificationDto, req: Request, res: Response): Promise<void>;
|
|
9
|
+
private processCalendarNotificationBatch;
|
|
10
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var CalendarController_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.CalendarController = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
19
|
+
const calendar_service_1 = require("../services/calendar/calendar.service");
|
|
20
|
+
const outlook_webhook_notification_dto_1 = require("../dto/outlook-webhook-notification.dto");
|
|
21
|
+
let CalendarController = CalendarController_1 = class CalendarController {
|
|
22
|
+
constructor(calendarService) {
|
|
23
|
+
this.calendarService = calendarService;
|
|
24
|
+
this.logger = new common_1.Logger(CalendarController_1.name);
|
|
25
|
+
}
|
|
26
|
+
async handleCalendarWebhook(validationToken, notificationBody, req, res) {
|
|
27
|
+
if (validationToken) {
|
|
28
|
+
this.logger.log('Handling Microsoft Graph validation request');
|
|
29
|
+
const decodedToken = decodeURIComponent(validationToken);
|
|
30
|
+
res.set('Content-Type', 'text/plain; charset=utf-8');
|
|
31
|
+
res.send(decodedToken);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
this.logger.debug(`Received webhook notification: ${JSON.stringify(notificationBody)}`);
|
|
36
|
+
if (Array.isArray(notificationBody.value) && notificationBody.value.length > 2) {
|
|
37
|
+
this.logger.log(`Received batch of ${notificationBody.value.length.toString()} notifications, responding with 202 Accepted`);
|
|
38
|
+
res.status(202).json({
|
|
39
|
+
success: true,
|
|
40
|
+
message: 'Notifications accepted for processing',
|
|
41
|
+
});
|
|
42
|
+
this.processCalendarNotificationBatch(notificationBody).catch((error) => {
|
|
43
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
44
|
+
this.logger.error(`Error processing notification batch: ${errorMessage}`);
|
|
45
|
+
});
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (Array.isArray(notificationBody.value) && notificationBody.value.length > 0) {
|
|
49
|
+
const results = await this.processCalendarNotificationBatch(notificationBody);
|
|
50
|
+
res.json({
|
|
51
|
+
success: true,
|
|
52
|
+
message: `Processed ${results.successCount.toString()} out of ${notificationBody.value.length.toString()} notifications`,
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this.logger.warn('Received webhook notification with unexpected format');
|
|
57
|
+
res.json({
|
|
58
|
+
success: true,
|
|
59
|
+
message: `Received webhook notification with unexpected format`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
64
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
65
|
+
this.logger.error(`Error processing webhook notification: ${errorMessage}`, errorStack);
|
|
66
|
+
res.status(500).json({
|
|
67
|
+
success: false,
|
|
68
|
+
message: 'Error processing webhook notification',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async processCalendarNotificationBatch(notificationBody) {
|
|
73
|
+
let successCount = 0;
|
|
74
|
+
let failureCount = 0;
|
|
75
|
+
const processedEvents = new Set();
|
|
76
|
+
for (const item of notificationBody.value) {
|
|
77
|
+
if (!item.subscriptionId || !item.resource) {
|
|
78
|
+
this.logger.warn(`Skipping notification with missing required fields`);
|
|
79
|
+
failureCount++;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const resourceData = item.resourceData;
|
|
83
|
+
if (resourceData.id && processedEvents.has(resourceData.id)) {
|
|
84
|
+
this.logger.debug(`Skipping duplicate event: ${resourceData.id}`);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (resourceData.id) {
|
|
88
|
+
processedEvents.add(resourceData.id);
|
|
89
|
+
}
|
|
90
|
+
const validChangeTypes = ['created', 'updated', 'deleted'];
|
|
91
|
+
if (!validChangeTypes.includes(item.changeType)) {
|
|
92
|
+
this.logger.warn(`Skipping notification with unsupported change type: ${item.changeType}`);
|
|
93
|
+
failureCount++;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const changeNotification = {
|
|
98
|
+
subscriptionId: item.subscriptionId,
|
|
99
|
+
subscriptionExpirationDateTime: item.subscriptionExpirationDateTime,
|
|
100
|
+
changeType: item.changeType,
|
|
101
|
+
resource: item.resource,
|
|
102
|
+
resourceData: resourceData,
|
|
103
|
+
clientState: item.clientState,
|
|
104
|
+
tenantId: item.tenantId,
|
|
105
|
+
};
|
|
106
|
+
const result = await this.calendarService.handleOutlookWebhook(changeNotification);
|
|
107
|
+
if (result.success) {
|
|
108
|
+
this.logger.log(`Successfully processed ${item.changeType} event for resource ID: ${resourceData.id || 'unknown'}`);
|
|
109
|
+
successCount++;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
this.logger.warn(`Failed to process event: ${result.message}`);
|
|
113
|
+
failureCount++;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
118
|
+
this.logger.error(`Error processing event: ${errorMessage}`);
|
|
119
|
+
failureCount++;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
this.logger.log(`Finished processing batch: ${successCount.toString()} succeeded, ${failureCount.toString()} failed`);
|
|
123
|
+
return { successCount, failureCount };
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
exports.CalendarController = CalendarController;
|
|
127
|
+
__decorate([
|
|
128
|
+
(0, common_1.Post)('webhook'),
|
|
129
|
+
(0, common_1.HttpCode)(200),
|
|
130
|
+
(0, swagger_1.ApiResponse)({
|
|
131
|
+
status: 200,
|
|
132
|
+
description: 'Webhook validation or notification processed successfully',
|
|
133
|
+
}),
|
|
134
|
+
(0, swagger_1.ApiResponse)({
|
|
135
|
+
status: 202,
|
|
136
|
+
description: 'Notification accepted for processing',
|
|
137
|
+
}),
|
|
138
|
+
(0, swagger_1.ApiResponse)({
|
|
139
|
+
status: 500,
|
|
140
|
+
description: 'Server error processing the notification',
|
|
141
|
+
}),
|
|
142
|
+
(0, swagger_1.ApiQuery)({
|
|
143
|
+
name: 'validationToken',
|
|
144
|
+
required: false,
|
|
145
|
+
description: 'Token sent by Microsoft Graph to validate the webhook endpoint',
|
|
146
|
+
}),
|
|
147
|
+
(0, swagger_1.ApiBody)({
|
|
148
|
+
description: 'Microsoft Graph webhook notification payload',
|
|
149
|
+
type: outlook_webhook_notification_dto_1.OutlookWebhookNotificationDto,
|
|
150
|
+
required: false,
|
|
151
|
+
}),
|
|
152
|
+
__param(0, (0, common_1.Query)('validationToken')),
|
|
153
|
+
__param(1, (0, common_1.Body)()),
|
|
154
|
+
__param(2, (0, common_1.Req)()),
|
|
155
|
+
__param(3, (0, common_1.Res)()),
|
|
156
|
+
__metadata("design:type", Function),
|
|
157
|
+
__metadata("design:paramtypes", [String, outlook_webhook_notification_dto_1.OutlookWebhookNotificationDto, Object, Object]),
|
|
158
|
+
__metadata("design:returntype", Promise)
|
|
159
|
+
], CalendarController.prototype, "handleCalendarWebhook", null);
|
|
160
|
+
exports.CalendarController = CalendarController = CalendarController_1 = __decorate([
|
|
161
|
+
(0, swagger_1.ApiTags)('Calendar'),
|
|
162
|
+
(0, common_1.Controller)('calendar'),
|
|
163
|
+
(0, common_1.Injectable)(),
|
|
164
|
+
__metadata("design:paramtypes", [calendar_service_1.CalendarService])
|
|
165
|
+
], CalendarController);
|
|
166
|
+
//# sourceMappingURL=calendar.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.controller.js","sourceRoot":"","sources":["../../src/controllers/calendar.controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Response, Request } from 'express';
|
|
2
|
+
import { EmailService } from '../services/email/email.service';
|
|
3
|
+
import { OutlookWebhookNotificationDto } from '../dto/outlook-webhook-notification.dto';
|
|
4
|
+
export declare class EmailController {
|
|
5
|
+
private readonly emailService;
|
|
6
|
+
private readonly logger;
|
|
7
|
+
constructor(emailService: EmailService);
|
|
8
|
+
handleEmailWebhook(validationToken: string, notificationBody: OutlookWebhookNotificationDto, req: Request, res: Response): Promise<void>;
|
|
9
|
+
private processEmailNotificationBatch;
|
|
10
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var EmailController_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.EmailController = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
19
|
+
const email_service_1 = require("../services/email/email.service");
|
|
20
|
+
const outlook_webhook_notification_dto_1 = require("../dto/outlook-webhook-notification.dto");
|
|
21
|
+
let EmailController = EmailController_1 = class EmailController {
|
|
22
|
+
constructor(emailService) {
|
|
23
|
+
this.emailService = emailService;
|
|
24
|
+
this.logger = new common_1.Logger(EmailController_1.name);
|
|
25
|
+
}
|
|
26
|
+
async handleEmailWebhook(validationToken, notificationBody, req, res) {
|
|
27
|
+
if (validationToken) {
|
|
28
|
+
this.logger.log('Handling Microsoft Graph validation request');
|
|
29
|
+
const decodedToken = decodeURIComponent(validationToken);
|
|
30
|
+
res.set('Content-Type', 'text/plain; charset=utf-8');
|
|
31
|
+
res.send(decodedToken);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
this.logger.debug(`Received email webhook notification: ${JSON.stringify(notificationBody)}`);
|
|
36
|
+
if (Array.isArray(notificationBody.value) && notificationBody.value.length > 2) {
|
|
37
|
+
this.logger.log(`Received batch of ${notificationBody.value.length.toString()} email notifications, responding with 202 Accepted`);
|
|
38
|
+
res.status(202).json({
|
|
39
|
+
success: true,
|
|
40
|
+
message: 'Email notifications accepted for processing',
|
|
41
|
+
});
|
|
42
|
+
this.processEmailNotificationBatch(notificationBody).catch((error) => {
|
|
43
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
44
|
+
this.logger.error(`Error processing email notification batch: ${errorMessage}`);
|
|
45
|
+
});
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (Array.isArray(notificationBody.value) && notificationBody.value.length > 0) {
|
|
49
|
+
const results = await this.processEmailNotificationBatch(notificationBody);
|
|
50
|
+
res.json({
|
|
51
|
+
success: true,
|
|
52
|
+
message: `Processed ${results.successCount.toString()} out of ${notificationBody.value.length.toString()} email notifications`,
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this.logger.warn('Received email webhook notification with unexpected format');
|
|
57
|
+
res.json({
|
|
58
|
+
success: true,
|
|
59
|
+
message: `Received email webhook notification with unexpected format`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
64
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
65
|
+
this.logger.error(`Error processing email webhook notification: ${errorMessage}`, errorStack);
|
|
66
|
+
res.status(500).json({
|
|
67
|
+
success: false,
|
|
68
|
+
message: 'Error processing email webhook notification',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async processEmailNotificationBatch(notificationBody) {
|
|
73
|
+
let successCount = 0;
|
|
74
|
+
let failureCount = 0;
|
|
75
|
+
const processedMessages = new Set();
|
|
76
|
+
for (const item of notificationBody.value) {
|
|
77
|
+
if (!item.subscriptionId || !item.resource) {
|
|
78
|
+
this.logger.warn(`Skipping email notification with missing required fields`);
|
|
79
|
+
failureCount++;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const resourceData = item.resourceData;
|
|
83
|
+
if (resourceData.id && processedMessages.has(resourceData.id)) {
|
|
84
|
+
this.logger.debug(`Skipping duplicate email: ${resourceData.id}`);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (resourceData.id) {
|
|
88
|
+
processedMessages.add(resourceData.id);
|
|
89
|
+
}
|
|
90
|
+
const validChangeTypes = ['created', 'updated', 'deleted'];
|
|
91
|
+
if (!validChangeTypes.includes(item.changeType)) {
|
|
92
|
+
this.logger.warn(`Skipping email notification with unsupported change type: ${item.changeType}`);
|
|
93
|
+
failureCount++;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const changeNotification = {
|
|
98
|
+
subscriptionId: item.subscriptionId,
|
|
99
|
+
subscriptionExpirationDateTime: item.subscriptionExpirationDateTime,
|
|
100
|
+
changeType: item.changeType,
|
|
101
|
+
resource: item.resource,
|
|
102
|
+
resourceData: resourceData,
|
|
103
|
+
clientState: item.clientState,
|
|
104
|
+
tenantId: item.tenantId,
|
|
105
|
+
};
|
|
106
|
+
const result = await this.emailService.handleEmailWebhook(changeNotification);
|
|
107
|
+
if (result.success) {
|
|
108
|
+
this.logger.log(`Successfully processed ${item.changeType} email for resource ID: ${resourceData.id || 'unknown'}`);
|
|
109
|
+
successCount++;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
this.logger.warn(`Failed to process email: ${result.message}`);
|
|
113
|
+
failureCount++;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
118
|
+
this.logger.error(`Error processing email event: ${errorMessage}`);
|
|
119
|
+
failureCount++;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
this.logger.log(`Finished processing email batch: ${successCount.toString()} succeeded, ${failureCount.toString()} failed`);
|
|
123
|
+
return { successCount, failureCount };
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
exports.EmailController = EmailController;
|
|
127
|
+
__decorate([
|
|
128
|
+
(0, common_1.Post)('webhook'),
|
|
129
|
+
(0, common_1.HttpCode)(200),
|
|
130
|
+
(0, swagger_1.ApiResponse)({
|
|
131
|
+
status: 200,
|
|
132
|
+
description: 'Webhook validation or notification processed successfully',
|
|
133
|
+
}),
|
|
134
|
+
(0, swagger_1.ApiResponse)({
|
|
135
|
+
status: 202,
|
|
136
|
+
description: 'Notification accepted for processing',
|
|
137
|
+
}),
|
|
138
|
+
(0, swagger_1.ApiResponse)({
|
|
139
|
+
status: 500,
|
|
140
|
+
description: 'Server error processing the notification',
|
|
141
|
+
}),
|
|
142
|
+
(0, swagger_1.ApiQuery)({
|
|
143
|
+
name: 'validationToken',
|
|
144
|
+
required: false,
|
|
145
|
+
description: 'Token sent by Microsoft Graph to validate the webhook endpoint',
|
|
146
|
+
}),
|
|
147
|
+
(0, swagger_1.ApiBody)({
|
|
148
|
+
description: 'Microsoft Graph webhook notification payload',
|
|
149
|
+
type: outlook_webhook_notification_dto_1.OutlookWebhookNotificationDto,
|
|
150
|
+
required: false,
|
|
151
|
+
}),
|
|
152
|
+
__param(0, (0, common_1.Query)('validationToken')),
|
|
153
|
+
__param(1, (0, common_1.Body)()),
|
|
154
|
+
__param(2, (0, common_1.Req)()),
|
|
155
|
+
__param(3, (0, common_1.Res)()),
|
|
156
|
+
__metadata("design:type", Function),
|
|
157
|
+
__metadata("design:paramtypes", [String, outlook_webhook_notification_dto_1.OutlookWebhookNotificationDto, Object, Object]),
|
|
158
|
+
__metadata("design:returntype", Promise)
|
|
159
|
+
], EmailController.prototype, "handleEmailWebhook", null);
|
|
160
|
+
exports.EmailController = EmailController = EmailController_1 = __decorate([
|
|
161
|
+
(0, swagger_1.ApiTags)('Email'),
|
|
162
|
+
(0, common_1.Controller)('email'),
|
|
163
|
+
(0, common_1.Injectable)(),
|
|
164
|
+
__metadata("design:paramtypes", [email_service_1.EmailService])
|
|
165
|
+
], EmailController);
|
|
166
|
+
//# sourceMappingURL=email.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.controller.js","sourceRoot":"","sources":["../../src/controllers/email.controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Response } from 'express';
|
|
2
|
-
import { MicrosoftAuthService } from '../services/microsoft-auth.service';
|
|
2
|
+
import { MicrosoftAuthService } from '../services/auth/microsoft-auth.service';
|
|
3
3
|
export declare class MicrosoftAuthController {
|
|
4
4
|
private readonly microsoftAuthService;
|
|
5
5
|
constructor(microsoftAuthService: MicrosoftAuthService);
|
|
@@ -15,7 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.MicrosoftAuthController = void 0;
|
|
16
16
|
const common_1 = require("@nestjs/common");
|
|
17
17
|
const swagger_1 = require("@nestjs/swagger");
|
|
18
|
-
const microsoft_auth_service_1 = require("../services/microsoft-auth.service");
|
|
18
|
+
const microsoft_auth_service_1 = require("../services/auth/microsoft-auth.service");
|
|
19
19
|
let MicrosoftAuthController = class MicrosoftAuthController {
|
|
20
20
|
constructor(microsoftAuthService) {
|
|
21
21
|
this.microsoftAuthService = microsoftAuthService;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"microsoft-auth.controller.js","sourceRoot":"","sources":["../../src/controllers/microsoft-auth.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAQwB;AAExB,6CAA4F;AAC5F
|
|
1
|
+
{"version":3,"file":"microsoft-auth.controller.js","sourceRoot":"","sources":["../../src/controllers/microsoft-auth.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAQwB;AAExB,6CAA4F;AAC5F,oFAA+E;AAIxE,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAClC,YAA6B,oBAA0C;QAA1C,yBAAoB,GAApB,oBAAoB,CAAsB;IAAG,CAAC;IA4DrE,AAAN,KAAK,CAAC,QAAQ,CAAgB,IAAY,EAAkB,KAAa,EAAS,GAAa;QAC7F,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,4BAAmB,CAAC,kBAAkB,CAAC,CAAC;QACpD,CAAC;QAED,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,4BAAmB,CAAC,6BAA6B,CAAC,CAAC;QAC/D,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAGlE,OAAO,GAAG,CAAC,MAAM,CAAC,mBAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC;;;;;;;;;;OAUrC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;YAC/C,MAAM,IAAI,qCAA4B,CAAC,0CAA0C,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;CACF,CAAA;AA1FY,0DAAuB;AA6D5B;IAvCL,IAAA,YAAG,EAAC,UAAU,CAAC;IACf,IAAA,sBAAY,EAAC;QACZ,OAAO,EAAE,kCAAkC;QAC3C,WAAW,EACT,2QAA2Q;KAC9Q,CAAC;IACD,IAAA,kBAAQ,EAAC;QACR,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,mCAAmC;QAChD,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,+CAA+C;KACzD,CAAC;IACD,IAAA,kBAAQ,EAAC;QACR,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,wDAAwD;QACrE,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,yCAAyC;KACnD,CAAC;IACD,IAAA,qBAAW,EAAC;QACX,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,8DAA8D;QAC3E,OAAO,EAAE;YACP,WAAW,EAAE;gBACX,OAAO,EACL,+FAA+F;aAClG;SACF;KACF,CAAC;IACD,IAAA,qBAAW,EAAC;QACX,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,0CAA0C;KACxD,CAAC;IACD,IAAA,qBAAW,EAAC;QACX,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,4CAA4C;KAC1D,CAAC;IACD,IAAA,qBAAW,EAAC,WAAW,CAAC;IACT,WAAA,IAAA,cAAK,EAAC,MAAM,CAAC,CAAA;IAAgB,WAAA,IAAA,cAAK,EAAC,OAAO,CAAC,CAAA;IAAiB,WAAA,IAAA,YAAG,GAAE,CAAA;;;;uDA4BhF;kCAzFU,uBAAuB;IAFnC,IAAA,iBAAO,EAAC,gBAAgB,CAAC;IACzB,IAAA,mBAAU,EAAC,gBAAgB,CAAC;qCAEwB,6CAAoB;GAD5D,uBAAuB,CA0FnC"}
|
|
@@ -3,6 +3,11 @@ export declare class OutlookResourceData {
|
|
|
3
3
|
'@odata.id'?: string;
|
|
4
4
|
'@odata.etag'?: string;
|
|
5
5
|
id: string;
|
|
6
|
+
userId?: number;
|
|
7
|
+
subscriptionId?: string;
|
|
8
|
+
resource?: string;
|
|
9
|
+
changeType?: string;
|
|
10
|
+
data?: Record<string, unknown>;
|
|
6
11
|
[key: string]: unknown;
|
|
7
12
|
}
|
|
8
13
|
export declare class OutlookWebhookNotificationItemDto {
|