@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.
Files changed (59) hide show
  1. package/README.md +160 -20
  2. package/dist/controllers/calendar.controller.d.ts +10 -0
  3. package/dist/controllers/calendar.controller.js +166 -0
  4. package/dist/controllers/calendar.controller.js.map +1 -0
  5. package/dist/controllers/email.controller.d.ts +10 -0
  6. package/dist/controllers/email.controller.js +166 -0
  7. package/dist/controllers/email.controller.js.map +1 -0
  8. package/dist/controllers/microsoft-auth.controller.d.ts +1 -1
  9. package/dist/controllers/microsoft-auth.controller.js +1 -1
  10. package/dist/controllers/microsoft-auth.controller.js.map +1 -1
  11. package/dist/dto/outlook-webhook-notification.dto.d.ts +5 -0
  12. package/dist/dto/outlook-webhook-notification.dto.js +39 -1
  13. package/dist/dto/outlook-webhook-notification.dto.js.map +1 -1
  14. package/dist/entities/outlook-webhook-subscription.entity.js +3 -4
  15. package/dist/entities/outlook-webhook-subscription.entity.js.map +1 -1
  16. package/dist/event-types.enum.d.ts +4 -1
  17. package/dist/event-types.enum.js +3 -0
  18. package/dist/event-types.enum.js.map +1 -1
  19. package/dist/index.d.ts +4 -3
  20. package/dist/index.js +4 -3
  21. package/dist/index.js.map +1 -1
  22. package/dist/microsoft-outlook.module.js +9 -6
  23. package/dist/microsoft-outlook.module.js.map +1 -1
  24. package/dist/migrations/1697025846000-CreateOutlookTables.js +2 -1
  25. package/dist/migrations/1697025846000-CreateOutlookTables.js.map +1 -1
  26. package/dist/migrations/1697026000000-EnsureUniqueSubscriptions.d.ts +5 -0
  27. package/dist/migrations/1697026000000-EnsureUniqueSubscriptions.js +27 -0
  28. package/dist/migrations/1697026000000-EnsureUniqueSubscriptions.js.map +1 -0
  29. package/dist/repositories/outlook-webhook-subscription.repository.js +14 -1
  30. package/dist/repositories/outlook-webhook-subscription.repository.js.map +1 -1
  31. package/dist/services/auth/index.d.ts +1 -0
  32. package/dist/services/auth/index.js +18 -0
  33. package/dist/services/auth/index.js.map +1 -0
  34. package/dist/services/{microsoft-auth.service.d.ts → auth/microsoft-auth.service.d.ts} +11 -7
  35. package/dist/services/{microsoft-auth.service.js → auth/microsoft-auth.service.js} +56 -27
  36. package/dist/services/auth/microsoft-auth.service.js.map +1 -0
  37. package/dist/services/{outlook.service.d.ts → calendar/calendar.service.d.ts} +6 -6
  38. package/dist/services/{outlook.service.js → calendar/calendar.service.js} +96 -66
  39. package/dist/services/calendar/calendar.service.js.map +1 -0
  40. package/dist/services/calendar/index.d.ts +1 -0
  41. package/dist/services/calendar/index.js +18 -0
  42. package/dist/services/calendar/index.js.map +1 -0
  43. package/dist/services/email/email.service.d.ts +24 -0
  44. package/dist/services/email/email.service.js +207 -0
  45. package/dist/services/email/email.service.js.map +1 -0
  46. package/dist/services/email/index.d.ts +1 -0
  47. package/dist/services/email/index.js +18 -0
  48. package/dist/services/email/index.js.map +1 -0
  49. package/dist/services/index.d.ts +3 -0
  50. package/dist/services/index.js +20 -0
  51. package/dist/services/index.js.map +1 -0
  52. package/dist/tsconfig.tsbuildinfo +1 -1
  53. package/dist/types/microsoft-graph.types.d.ts +1 -1
  54. package/package.json +6 -2
  55. package/dist/controllers/outlook.controller.d.ts +0 -8
  56. package/dist/controllers/outlook.controller.js +0 -117
  57. package/dist/controllers/outlook.controller.js.map +0 -1
  58. package/dist/services/microsoft-auth.service.js.map +0 -1
  59. 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. Import Required Modules
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
- ### 3. Create a Login Controller
139
+ ### 4. Create an Auth Controller
126
140
 
127
- Create a controller to handle Microsoft authentication:
141
+ The library provides a MicrosoftAuthController for handling authentication, but you can also create your own:
128
142
 
129
143
  ```typescript
130
- export class CalendarController {
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
- @UseGuards(AuthGuard)
136
- @Get('auth/microsoft/login')
137
- async login(@Req() req: Request) {
138
- const user = req.user as UserTokenPayload;
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(user.id.toString());
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
- - `OutlookService` - Main service for Microsoft Graph API operations on Outlook
152
- - `MicrosoftAuthService` - For authentication and token management
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
- These events are emitted when Microsoft Graph sends webhook notifications to your application for calendar events changes.
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,+EAA0E;AAInE,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"}
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 {