@checkfirst/nestjs-outlook 0.1.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/LICENSE +21 -0
  2. package/README.md +224 -0
  3. package/assets/checkfirst-logo.png +0 -0
  4. package/dist/constants.d.ts +1 -0
  5. package/dist/constants.js +5 -0
  6. package/dist/constants.js.map +1 -0
  7. package/dist/controllers/microsoft-auth.controller.d.ts +7 -0
  8. package/dist/controllers/microsoft-auth.controller.js +101 -0
  9. package/dist/controllers/microsoft-auth.controller.js.map +1 -0
  10. package/dist/controllers/outlook.controller.d.ts +8 -0
  11. package/dist/controllers/outlook.controller.js +117 -0
  12. package/dist/controllers/outlook.controller.js.map +1 -0
  13. package/dist/dto/outlook-webhook-notification.dto.d.ts +19 -0
  14. package/dist/dto/outlook-webhook-notification.dto.js +149 -0
  15. package/dist/dto/outlook-webhook-notification.dto.js.map +1 -0
  16. package/dist/entities/csrf-token.entity.d.ts +7 -0
  17. package/dist/entities/csrf-token.entity.js +48 -0
  18. package/dist/entities/csrf-token.entity.js.map +1 -0
  19. package/dist/entities/outlook-webhook-subscription.entity.d.ts +15 -0
  20. package/dist/entities/outlook-webhook-subscription.entity.js +87 -0
  21. package/dist/entities/outlook-webhook-subscription.entity.js.map +1 -0
  22. package/dist/event-types.enum.d.ts +7 -0
  23. package/dist/event-types.enum.js +12 -0
  24. package/dist/event-types.enum.js.map +1 -0
  25. package/dist/index.d.ts +11 -0
  26. package/dist/index.js +28 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/interfaces/config/outlook-config.interface.d.ts +7 -0
  29. package/dist/interfaces/config/outlook-config.interface.js +3 -0
  30. package/dist/interfaces/config/outlook-config.interface.js.map +1 -0
  31. package/dist/interfaces/microsoft-auth/microsoft-token-api-response.interface.d.ts +9 -0
  32. package/dist/interfaces/microsoft-auth/microsoft-token-api-response.interface.js +3 -0
  33. package/dist/interfaces/microsoft-auth/microsoft-token-api-response.interface.js.map +1 -0
  34. package/dist/interfaces/microsoft-auth/state-object.interface.d.ts +5 -0
  35. package/dist/interfaces/microsoft-auth/state-object.interface.js +3 -0
  36. package/dist/interfaces/microsoft-auth/state-object.interface.js.map +1 -0
  37. package/dist/interfaces/outlook/token-response.interface.d.ts +5 -0
  38. package/dist/interfaces/outlook/token-response.interface.js +3 -0
  39. package/dist/interfaces/outlook/token-response.interface.js.map +1 -0
  40. package/dist/microsoft-outlook.module.d.ts +4 -0
  41. package/dist/microsoft-outlook.module.js +50 -0
  42. package/dist/microsoft-outlook.module.js.map +1 -0
  43. package/dist/migrations/1697025846000-CreateOutlookTables.d.ts +5 -0
  44. package/dist/migrations/1697025846000-CreateOutlookTables.js +40 -0
  45. package/dist/migrations/1697025846000-CreateOutlookTables.js.map +1 -0
  46. package/dist/repositories/microsoft-csrf-token.repository.d.ts +9 -0
  47. package/dist/repositories/microsoft-csrf-token.repository.js +60 -0
  48. package/dist/repositories/microsoft-csrf-token.repository.js.map +1 -0
  49. package/dist/repositories/outlook-webhook-subscription.repository.d.ts +12 -0
  50. package/dist/repositories/outlook-webhook-subscription.repository.js +70 -0
  51. package/dist/repositories/outlook-webhook-subscription.repository.js.map +1 -0
  52. package/dist/services/microsoft-auth.service.d.ts +32 -0
  53. package/dist/services/microsoft-auth.service.js +254 -0
  54. package/dist/services/microsoft-auth.service.js.map +1 -0
  55. package/dist/services/outlook.service.d.ts +28 -0
  56. package/dist/services/outlook.service.js +265 -0
  57. package/dist/services/outlook.service.js.map +1 -0
  58. package/dist/tsconfig.tsbuildinfo +1 -0
  59. package/package.json +103 -0
@@ -0,0 +1,60 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.MicrosoftCsrfTokenRepository = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const typeorm_1 = require("@nestjs/typeorm");
18
+ const typeorm_2 = require("typeorm");
19
+ const csrf_token_entity_1 = require("../entities/csrf-token.entity");
20
+ let MicrosoftCsrfTokenRepository = class MicrosoftCsrfTokenRepository {
21
+ constructor(repository) {
22
+ this.repository = repository;
23
+ }
24
+ async saveToken(token, userId, expiresInMs) {
25
+ const expires = new Date(Date.now() + expiresInMs);
26
+ const csrfToken = new csrf_token_entity_1.MicrosoftCsrfToken();
27
+ csrfToken.token = token;
28
+ csrfToken.userId = userId.toString();
29
+ csrfToken.expires = expires;
30
+ return this.repository.save(csrfToken);
31
+ }
32
+ async findAndValidateToken(token) {
33
+ if (!token) {
34
+ return null;
35
+ }
36
+ const csrfToken = await this.repository.findOne({
37
+ where: { token },
38
+ });
39
+ if (!csrfToken) {
40
+ return null;
41
+ }
42
+ if (csrfToken.expires < new Date()) {
43
+ await this.repository.delete(csrfToken.id);
44
+ return null;
45
+ }
46
+ await this.repository.delete(csrfToken.id);
47
+ return csrfToken;
48
+ }
49
+ async cleanupExpiredTokens() {
50
+ const now = new Date();
51
+ await this.repository.delete({ expires: (0, typeorm_2.LessThan)(now) });
52
+ }
53
+ };
54
+ exports.MicrosoftCsrfTokenRepository = MicrosoftCsrfTokenRepository;
55
+ exports.MicrosoftCsrfTokenRepository = MicrosoftCsrfTokenRepository = __decorate([
56
+ (0, common_1.Injectable)(),
57
+ __param(0, (0, typeorm_1.InjectRepository)(csrf_token_entity_1.MicrosoftCsrfToken)),
58
+ __metadata("design:paramtypes", [typeorm_2.Repository])
59
+ ], MicrosoftCsrfTokenRepository);
60
+ //# sourceMappingURL=microsoft-csrf-token.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microsoft-csrf-token.repository.js","sourceRoot":"","sources":["../../src/repositories/microsoft-csrf-token.repository.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6CAAmD;AACnD,qCAA+C;AAC/C,qEAAmE;AAG5D,IAAM,4BAA4B,GAAlC,MAAM,4BAA4B;IACvC,YAEmB,UAA0C;QAA1C,eAAU,GAAV,UAAU,CAAgC;IAC1D,CAAC;IAQJ,KAAK,CAAC,SAAS,CACb,KAAa,EACb,MAAuB,EACvB,WAAmB;QAEnB,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,CAAC;QAEnD,MAAM,SAAS,GAAG,IAAI,sCAAkB,EAAE,CAAC;QAC3C,SAAS,CAAC,KAAK,GAAG,KAAK,CAAC;QACxB,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrC,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC;QAE5B,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAOD,KAAK,CAAC,oBAAoB,CAAC,KAAa;QACtC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QAGD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAC9C,KAAK,EAAE,EAAE,KAAK,EAAE;SACjB,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;QAGD,IAAI,SAAS,CAAC,OAAO,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;YAEnC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YAC3C,OAAO,IAAI,CAAC;QACd,CAAC;QAGD,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAE3C,OAAO,SAAS,CAAC;IACnB,CAAC;IAKD,KAAK,CAAC,oBAAoB;QACxB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,IAAA,kBAAQ,EAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3D,CAAC;CACF,CAAA;AAlEY,oEAA4B;uCAA5B,4BAA4B;IADxC,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,0BAAgB,EAAC,sCAAkB,CAAC,CAAA;qCACR,oBAAU;GAH9B,4BAA4B,CAkExC"}
@@ -0,0 +1,12 @@
1
+ import { Repository } from 'typeorm';
2
+ import { OutlookWebhookSubscription } from '../entities/outlook-webhook-subscription.entity';
3
+ export declare class OutlookWebhookSubscriptionRepository {
4
+ private readonly repository;
5
+ constructor(repository: Repository<OutlookWebhookSubscription>);
6
+ saveSubscription(subscription: Partial<OutlookWebhookSubscription>): Promise<OutlookWebhookSubscription>;
7
+ findBySubscriptionId(subscriptionId: string): Promise<OutlookWebhookSubscription | null>;
8
+ updateSubscriptionExpiration(subscriptionId: string, expirationDateTime: Date, accessToken?: string): Promise<void>;
9
+ deactivateSubscription(subscriptionId: string): Promise<void>;
10
+ findSubscriptionsNeedingRenewal(hoursUntilExpiration: number): Promise<OutlookWebhookSubscription[]>;
11
+ findActiveSubscriptions(): Promise<OutlookWebhookSubscription[]>;
12
+ }
@@ -0,0 +1,70 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.OutlookWebhookSubscriptionRepository = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const typeorm_1 = require("@nestjs/typeorm");
18
+ const typeorm_2 = require("typeorm");
19
+ const outlook_webhook_subscription_entity_1 = require("../entities/outlook-webhook-subscription.entity");
20
+ let OutlookWebhookSubscriptionRepository = class OutlookWebhookSubscriptionRepository {
21
+ constructor(repository) {
22
+ this.repository = repository;
23
+ }
24
+ async saveSubscription(subscription) {
25
+ const newSubscription = this.repository.create(subscription);
26
+ return this.repository.save(newSubscription);
27
+ }
28
+ async findBySubscriptionId(subscriptionId) {
29
+ return this.repository.findOne({ where: { subscriptionId, isActive: true } });
30
+ }
31
+ async updateSubscriptionExpiration(subscriptionId, expirationDateTime, accessToken) {
32
+ const update = {
33
+ expirationDateTime,
34
+ updatedAt: new Date(),
35
+ };
36
+ if (accessToken) {
37
+ update.accessToken = accessToken;
38
+ }
39
+ await this.repository.update({ subscriptionId, isActive: true }, update);
40
+ }
41
+ async deactivateSubscription(subscriptionId) {
42
+ await this.repository.update({ subscriptionId }, { isActive: false, updatedAt: new Date() });
43
+ }
44
+ async findSubscriptionsNeedingRenewal(hoursUntilExpiration) {
45
+ const expirationThreshold = new Date();
46
+ expirationThreshold.setHours(expirationThreshold.getHours() + hoursUntilExpiration);
47
+ return this.repository.find({
48
+ where: {
49
+ isActive: true,
50
+ expirationDateTime: (0, typeorm_2.LessThan)(expirationThreshold),
51
+ },
52
+ });
53
+ }
54
+ async findActiveSubscriptions() {
55
+ const now = new Date();
56
+ return this.repository.find({
57
+ where: {
58
+ isActive: true,
59
+ expirationDateTime: (0, typeorm_2.MoreThan)(now),
60
+ },
61
+ });
62
+ }
63
+ };
64
+ exports.OutlookWebhookSubscriptionRepository = OutlookWebhookSubscriptionRepository;
65
+ exports.OutlookWebhookSubscriptionRepository = OutlookWebhookSubscriptionRepository = __decorate([
66
+ (0, common_1.Injectable)(),
67
+ __param(0, (0, typeorm_1.InjectRepository)(outlook_webhook_subscription_entity_1.OutlookWebhookSubscription)),
68
+ __metadata("design:paramtypes", [typeorm_2.Repository])
69
+ ], OutlookWebhookSubscriptionRepository);
70
+ //# sourceMappingURL=outlook-webhook-subscription.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outlook-webhook-subscription.repository.js","sourceRoot":"","sources":["../../src/repositories/outlook-webhook-subscription.repository.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6CAAmD;AACnD,qCAAyD;AACzD,yGAA6F;AAGtF,IAAM,oCAAoC,GAA1C,MAAM,oCAAoC;IAC/C,YAEmB,UAAkD;QAAlD,eAAU,GAAV,UAAU,CAAwC;IAClE,CAAC;IAEJ,KAAK,CAAC,gBAAgB,CACpB,YAAiD;QAEjD,MAAM,eAAe,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,cAAsB;QAC/C,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,4BAA4B,CAChC,cAAsB,EACtB,kBAAwB,EACxB,WAAoB;QAEpB,MAAM,MAAM,GAAwC;YAClD,kBAAkB;YAClB,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC;QAEF,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;QACnC,CAAC;QAED,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,cAAsB;QACjD,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,KAAK,CAAC,+BAA+B,CACnC,oBAA4B;QAE5B,MAAM,mBAAmB,GAAG,IAAI,IAAI,EAAE,CAAC;QACvC,mBAAmB,CAAC,QAAQ,CAAC,mBAAmB,CAAC,QAAQ,EAAE,GAAG,oBAAoB,CAAC,CAAC;QAEpF,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE;gBACL,QAAQ,EAAE,IAAI;gBACd,kBAAkB,EAAE,IAAA,kBAAQ,EAAC,mBAAmB,CAAC;aAClD;SACF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,uBAAuB;QAC3B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE;gBACL,QAAQ,EAAE,IAAI;gBACd,kBAAkB,EAAE,IAAA,kBAAQ,EAAC,GAAG,CAAC;aAClC;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AA7DY,oFAAoC;+CAApC,oCAAoC;IADhD,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,0BAAgB,EAAC,gEAA0B,CAAC,CAAA;qCAChB,oBAAU;GAH9B,oCAAoC,CA6DhD"}
@@ -0,0 +1,32 @@
1
+ import { EventEmitter2 } from '@nestjs/event-emitter';
2
+ import { TokenResponse } from '../interfaces/outlook/token-response.interface';
3
+ import { OutlookService } from './outlook.service';
4
+ import { Subscription } from '@microsoft/microsoft-graph-types';
5
+ import { MicrosoftOutlookConfig } from '../interfaces/config/outlook-config.interface';
6
+ import { MicrosoftCsrfTokenRepository } from '../repositories/microsoft-csrf-token.repository';
7
+ import { StateObject } from '../interfaces/microsoft-auth/state-object.interface';
8
+ export declare class MicrosoftAuthService {
9
+ private readonly eventEmitter;
10
+ private readonly outlookService;
11
+ private readonly microsoftConfig;
12
+ private readonly csrfTokenRepository;
13
+ private readonly logger;
14
+ private readonly clientId;
15
+ private readonly clientSecret;
16
+ private readonly tenantId;
17
+ private readonly redirectUri;
18
+ private readonly tokenEndpoint;
19
+ private readonly scope;
20
+ private readonly CSRF_TOKEN_EXPIRY;
21
+ constructor(eventEmitter: EventEmitter2, outlookService: OutlookService, microsoftConfig: MicrosoftOutlookConfig, csrfTokenRepository: MicrosoftCsrfTokenRepository);
22
+ private buildRedirectUri;
23
+ cleanupExpiredTokens(): Promise<void>;
24
+ private generateCsrfToken;
25
+ parseState(state: string): StateObject | null;
26
+ validateCsrfToken(token: string, timestamp?: number): Promise<string | null>;
27
+ getLoginUrl(userId: string): Promise<string>;
28
+ exchangeCodeForToken(code: string, state: string): Promise<TokenResponse>;
29
+ refreshAccessToken(refreshToken: string, userId?: number, calendarId?: string): Promise<TokenResponse>;
30
+ renewWebhookSubscription(subscriptionId: string, accessToken: string, refreshToken: string): Promise<Subscription>;
31
+ isTokenExpired(tokenExpiry: Date, bufferMinutes?: number): boolean;
32
+ }
@@ -0,0 +1,254 @@
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 MicrosoftAuthService_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.MicrosoftAuthService = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const event_emitter_1 = require("@nestjs/event-emitter");
19
+ const axios_1 = require("axios");
20
+ const qs = require("querystring");
21
+ const outlook_service_1 = require("./outlook.service");
22
+ const constants_1 = require("../constants");
23
+ const event_types_enum_1 = require("../event-types.enum");
24
+ const crypto = require("crypto");
25
+ const schedule_1 = require("@nestjs/schedule");
26
+ const microsoft_csrf_token_repository_1 = require("../repositories/microsoft-csrf-token.repository");
27
+ let MicrosoftAuthService = MicrosoftAuthService_1 = class MicrosoftAuthService {
28
+ constructor(eventEmitter, outlookService, microsoftConfig, csrfTokenRepository) {
29
+ this.eventEmitter = eventEmitter;
30
+ this.outlookService = outlookService;
31
+ this.microsoftConfig = microsoftConfig;
32
+ this.csrfTokenRepository = csrfTokenRepository;
33
+ this.logger = new common_1.Logger(MicrosoftAuthService_1.name);
34
+ this.tenantId = 'common';
35
+ this.CSRF_TOKEN_EXPIRY = 30 * 60 * 1000;
36
+ console.log('MicrosoftAuthService constructor - microsoftConfig:', {
37
+ clientId: this.microsoftConfig.clientId,
38
+ redirectUri: this.microsoftConfig.redirectPath,
39
+ });
40
+ this.clientId = this.microsoftConfig.clientId;
41
+ this.clientSecret = this.microsoftConfig.clientSecret;
42
+ this.redirectUri = this.buildRedirectUri(this.microsoftConfig);
43
+ console.log('Redirect URI:', this.redirectUri);
44
+ this.tokenEndpoint = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
45
+ this.scope = ['offline_access', 'Calendars.ReadWrite', 'Calendars.Read', 'User.Read'].join(' ');
46
+ this.logger.log(`Microsoft OAuth redirect URI set to: ${this.redirectUri}`);
47
+ }
48
+ buildRedirectUri(config) {
49
+ if (config.redirectPath && config.redirectPath.startsWith('http')) {
50
+ this.logger.log(`Using complete redirect URI from config: ${config.redirectPath}`);
51
+ return config.redirectPath;
52
+ }
53
+ const baseUrl = config.backendBaseUrl || 'http://localhost:3000';
54
+ const cleanBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
55
+ let path = '';
56
+ if (config.basePath) {
57
+ const cleanBasePath = config.basePath.replace(/^\/+|\/+$/g, '');
58
+ path += `/${cleanBasePath}`;
59
+ }
60
+ if (config.redirectPath) {
61
+ const cleanRedirectPath = config.redirectPath.replace(/^\/+/g, '');
62
+ path += `/${cleanRedirectPath}`;
63
+ }
64
+ else {
65
+ path += '/api/v1/auth/microsoft/callback';
66
+ }
67
+ path = path.replace(/\/+/g, '/');
68
+ const finalUri = `${cleanBaseUrl}${path}`;
69
+ this.logger.log(`Constructed redirect URI: ${finalUri}`);
70
+ this.logger.debug(`Using config: baseUrl=${baseUrl}, basePath=${config.basePath || ''}, redirectPath=${config.redirectPath || ''}`);
71
+ return finalUri;
72
+ }
73
+ async cleanupExpiredTokens() {
74
+ try {
75
+ await this.csrfTokenRepository.cleanupExpiredTokens();
76
+ this.logger.log('Cleaned up expired CSRF tokens');
77
+ }
78
+ catch (error) {
79
+ this.logger.error(`Error cleaning up expired tokens: ${error instanceof Error ? error.message : 'Unknown error'}`);
80
+ }
81
+ }
82
+ async generateCsrfToken(userId) {
83
+ const token = crypto.randomBytes(32).toString('hex');
84
+ await this.csrfTokenRepository.saveToken(token, userId, this.CSRF_TOKEN_EXPIRY);
85
+ return token;
86
+ }
87
+ parseState(state) {
88
+ try {
89
+ const paddingNeeded = 4 - (state.length % 4);
90
+ const paddedState = paddingNeeded < 4 ? state + '='.repeat(paddingNeeded) : state;
91
+ const decoded = Buffer.from(paddedState, 'base64').toString();
92
+ return JSON.parse(decoded);
93
+ }
94
+ catch (error) {
95
+ this.logger.error(`Failed to parse state: ${error instanceof Error ? error.message : 'Unknown error'}`);
96
+ return null;
97
+ }
98
+ }
99
+ async validateCsrfToken(token, timestamp) {
100
+ if (!token) {
101
+ return 'Missing CSRF token';
102
+ }
103
+ const csrfToken = await this.csrfTokenRepository.findAndValidateToken(token);
104
+ if (!csrfToken) {
105
+ this.logger.warn('CSRF token not found or expired');
106
+ return 'Invalid or expired CSRF token';
107
+ }
108
+ if (timestamp && Date.now() - timestamp > this.CSRF_TOKEN_EXPIRY) {
109
+ this.logger.warn(`Request timestamp expired for user ${csrfToken.userId}`);
110
+ return 'Authorization request has expired';
111
+ }
112
+ return null;
113
+ }
114
+ async getLoginUrl(userId) {
115
+ const csrf = await this.generateCsrfToken(userId);
116
+ const stateObj = {
117
+ userId,
118
+ csrf,
119
+ timestamp: Date.now(),
120
+ };
121
+ const stateJson = JSON.stringify(stateObj);
122
+ const state = Buffer.from(stateJson).toString('base64').replace(/=/g, '');
123
+ this.logger.log(`State object: ${JSON.stringify(stateObj)}`);
124
+ const encodedRedirectUri = encodeURIComponent(this.redirectUri);
125
+ const encodedScope = encodeURIComponent(this.scope);
126
+ this.logger.log(`Redirect URI (raw): ${this.redirectUri}`);
127
+ this.logger.log(`Redirect URI (encoded): ${encodedRedirectUri}`);
128
+ const authorizeUrl = `https://login.microsoftonline.com/${this.tenantId}/oauth2/v2.0/authorize` +
129
+ `?client_id=${this.clientId}` +
130
+ `&response_type=code` +
131
+ `&redirect_uri=${encodedRedirectUri}` +
132
+ `&response_mode=query` +
133
+ `&scope=${encodedScope}` +
134
+ `&state=${state}`;
135
+ this.logger.log(`FINAL MICROSOFT LOGIN URL: ${authorizeUrl}`);
136
+ return authorizeUrl;
137
+ }
138
+ async exchangeCodeForToken(code, state) {
139
+ const stateData = this.parseState(state);
140
+ if (!stateData || !stateData.userId) {
141
+ throw new Error('Invalid state parameter - missing user ID');
142
+ }
143
+ const csrfError = await this.validateCsrfToken(stateData.csrf, stateData.timestamp);
144
+ if (csrfError) {
145
+ this.logger.error(`CSRF validation failed for user ${String(stateData.userId)}: ${csrfError}`);
146
+ throw new Error(`CSRF validation failed: ${csrfError}`);
147
+ }
148
+ try {
149
+ this.logger.log(`Exchanging code for token with redirect URI: ${this.redirectUri}`);
150
+ const postData = new URLSearchParams({
151
+ client_id: this.clientId,
152
+ scope: this.scope,
153
+ code: code,
154
+ redirect_uri: this.redirectUri,
155
+ grant_type: 'authorization_code',
156
+ client_secret: this.clientSecret,
157
+ });
158
+ this.logger.log(`Token request payload: ${postData.toString()}`);
159
+ const tokenResponse = await axios_1.default.post(this.tokenEndpoint, postData, {
160
+ headers: {
161
+ 'Content-Type': 'application/x-www-form-urlencoded',
162
+ },
163
+ });
164
+ const tokenData = {
165
+ access_token: tokenResponse.data.access_token,
166
+ refresh_token: tokenResponse.data.refresh_token || '',
167
+ expires_in: tokenResponse.data.expires_in,
168
+ };
169
+ await Promise.resolve(this.eventEmitter.emit(event_types_enum_1.OutlookEventTypes.AUTH_TOKENS_SAVE, stateData.userId, tokenData));
170
+ try {
171
+ await this.outlookService.createWebhookSubscription(Number(stateData.userId), tokenData.access_token, tokenData.refresh_token);
172
+ this.logger.log(`Successfully created webhook subscription for user ${String(stateData.userId)}`);
173
+ }
174
+ catch (webhookError) {
175
+ this.logger.error(`Failed to create webhook subscription: ${webhookError instanceof Error ? webhookError.message : 'Unknown error'}`);
176
+ }
177
+ return tokenData;
178
+ }
179
+ catch (error) {
180
+ this.logger.error(`Error exchanging code for token:`, error);
181
+ throw new Error('Failed to exchange code for token');
182
+ }
183
+ }
184
+ async refreshAccessToken(refreshToken, userId, calendarId) {
185
+ try {
186
+ const payload = {
187
+ client_id: this.clientId,
188
+ client_secret: this.clientSecret,
189
+ refresh_token: refreshToken,
190
+ grant_type: 'refresh_token',
191
+ scope: this.scope,
192
+ };
193
+ const response = await axios_1.default.post(this.tokenEndpoint, qs.stringify(payload), {
194
+ headers: {
195
+ 'Content-Type': 'application/x-www-form-urlencoded',
196
+ },
197
+ });
198
+ if (!response.data.access_token || !response.data.expires_in) {
199
+ throw new Error('Invalid token refresh response from Microsoft');
200
+ }
201
+ const newRefreshToken = response.data.refresh_token || refreshToken;
202
+ const tokenData = {
203
+ access_token: response.data.access_token,
204
+ refresh_token: newRefreshToken,
205
+ expires_in: response.data.expires_in,
206
+ };
207
+ if (userId !== undefined && calendarId) {
208
+ const userIdStr = String(userId);
209
+ const calendarIdStr = String(calendarId);
210
+ await Promise.resolve(this.eventEmitter.emit(event_types_enum_1.OutlookEventTypes.AUTH_TOKENS_UPDATE, userIdStr, calendarIdStr, tokenData));
211
+ }
212
+ return tokenData;
213
+ }
214
+ catch (error) {
215
+ this.logger.error('Error refreshing access token:', error);
216
+ throw new Error('Failed to refresh access token from Microsoft');
217
+ }
218
+ }
219
+ async renewWebhookSubscription(subscriptionId, accessToken, refreshToken) {
220
+ try {
221
+ try {
222
+ return await this.outlookService.renewWebhookSubscription(subscriptionId, accessToken);
223
+ }
224
+ catch (error) {
225
+ this.logger.warn(`Access token might be expired, attempting refresh: ${error instanceof Error ? error.message : 'Unknown error'}`);
226
+ const newTokens = await this.refreshAccessToken(refreshToken);
227
+ return await this.outlookService.renewWebhookSubscription(subscriptionId, newTokens.access_token);
228
+ }
229
+ }
230
+ catch (error) {
231
+ this.logger.error(`Failed to renew webhook subscription: ${error instanceof Error ? error.message : 'Unknown error'}`);
232
+ throw new Error('Failed to renew webhook subscription');
233
+ }
234
+ }
235
+ isTokenExpired(tokenExpiry, bufferMinutes = 5) {
236
+ const currentTimeWithBuffer = new Date(Date.now() + bufferMinutes * 60 * 1000);
237
+ return tokenExpiry < currentTimeWithBuffer;
238
+ }
239
+ };
240
+ exports.MicrosoftAuthService = MicrosoftAuthService;
241
+ __decorate([
242
+ (0, schedule_1.Cron)(schedule_1.CronExpression.EVERY_DAY_AT_MIDNIGHT),
243
+ __metadata("design:type", Function),
244
+ __metadata("design:paramtypes", []),
245
+ __metadata("design:returntype", Promise)
246
+ ], MicrosoftAuthService.prototype, "cleanupExpiredTokens", null);
247
+ exports.MicrosoftAuthService = MicrosoftAuthService = MicrosoftAuthService_1 = __decorate([
248
+ (0, common_1.Injectable)(),
249
+ __param(1, (0, common_1.Inject)((0, common_1.forwardRef)(() => outlook_service_1.OutlookService))),
250
+ __param(2, (0, common_1.Inject)(constants_1.MICROSOFT_CONFIG)),
251
+ __metadata("design:paramtypes", [event_emitter_1.EventEmitter2,
252
+ outlook_service_1.OutlookService, Object, microsoft_csrf_token_repository_1.MicrosoftCsrfTokenRepository])
253
+ ], MicrosoftAuthService);
254
+ //# sourceMappingURL=microsoft-auth.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microsoft-auth.service.js","sourceRoot":"","sources":["../../src/services/microsoft-auth.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { EventEmitter2 } from '@nestjs/event-emitter';
2
+ import { Event, Subscription, ChangeNotification } from '@microsoft/microsoft-graph-types';
3
+ import { MicrosoftAuthService } from './microsoft-auth.service';
4
+ import { TokenResponse } from '../interfaces/outlook/token-response.interface';
5
+ import { OutlookWebhookSubscriptionRepository } from '../repositories/outlook-webhook-subscription.repository';
6
+ import { MicrosoftOutlookConfig } from '../interfaces/config/outlook-config.interface';
7
+ export declare class OutlookService {
8
+ private readonly microsoftAuthService;
9
+ private readonly webhookSubscriptionRepository;
10
+ private readonly eventEmitter;
11
+ private readonly microsoftConfig;
12
+ private readonly logger;
13
+ constructor(microsoftAuthService: MicrosoftAuthService, webhookSubscriptionRepository: OutlookWebhookSubscriptionRepository, eventEmitter: EventEmitter2, microsoftConfig: MicrosoftOutlookConfig);
14
+ getDefaultCalendarId(accessToken: string): Promise<string>;
15
+ createEvent(event: Partial<Event>, accessToken: string, refreshToken: string, tokenExpiry: string | undefined, userId: number, calendarId: string): Promise<{
16
+ event: Event;
17
+ tokensRefreshed: boolean;
18
+ refreshedTokens?: TokenResponse;
19
+ }>;
20
+ createWebhookSubscription(userId: number, accessToken: string, refreshToken: string): Promise<Subscription>;
21
+ renewWebhookSubscription(subscriptionId: string, accessToken: string): Promise<Subscription>;
22
+ deleteWebhookSubscription(subscriptionId: string, accessToken: string): Promise<boolean>;
23
+ renewSubscriptions(): Promise<void>;
24
+ handleOutlookWebhook(notificationItem: ChangeNotification): Promise<{
25
+ success: boolean;
26
+ message: string;
27
+ }>;
28
+ }