UNPKG

@checkfirst/nestjs-outlook

Version:

An opinionated NestJS module for Microsoft Outlook integration that provides easy access to Microsoft Graph API for emails, calendars, and more.

159 lines โ€ข 7.66 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 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; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var MicrosoftSubscriptionService_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.MicrosoftSubscriptionService = void 0; const common_1 = require("@nestjs/common"); const axios_1 = require("axios"); let MicrosoftSubscriptionService = MicrosoftSubscriptionService_1 = class MicrosoftSubscriptionService { constructor() { this.logger = new common_1.Logger(MicrosoftSubscriptionService_1.name); this.graphApiBaseUrl = 'https://graph.microsoft.com/v1.0'; this.msAuthUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0'; } async getActiveSubscriptions(accessToken) { try { const response = await axios_1.default.get(`${this.graphApiBaseUrl}/subscriptions`, { headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, timeout: 10000, }); const data = response.data; return data.value || []; } catch (error) { const message = error instanceof Error ? error.message : 'Unknown error'; this.logger.warn(`Failed to get subscriptions from Microsoft: ${message}`); return []; } } async getActiveSubscriptionsForClient(clientId, accessToken) { const allSubscriptions = await this.getActiveSubscriptions(accessToken); return allSubscriptions.filter((sub) => { var _a; return (_a = sub.clientState) === null || _a === void 0 ? void 0 : _a.includes(`client_${clientId}_`); }); } async getActiveSubscriptionsForUser(userId, accessToken) { const allSubscriptions = await this.getActiveSubscriptions(accessToken); return allSubscriptions.filter((sub) => { var _a; return (_a = sub.clientState) === null || _a === void 0 ? void 0 : _a.includes(`user_${userId}_`); }); } async deleteSubscription(subscriptionId, accessToken) { var _a; try { await axios_1.default.delete(`${this.graphApiBaseUrl}/subscriptions/${subscriptionId}`, { headers: { Authorization: `Bearer ${accessToken}`, }, timeout: 10000, }); this.logger.log(`โœ… Deleted subscription ${subscriptionId} at Microsoft`); } catch (error) { if (axios_1.default.isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) { this.logger.log(`Subscription ${subscriptionId} already deleted at Microsoft`); return; } throw error; } } async cleanupSubscriptions(options) { const { accessToken, filter } = options; const result = { totalFound: 0, successfullyDeleted: 0, failedToDelete: 0, deletedSubscriptionIds: [], errors: [], }; try { this.logger.log('๐Ÿงน Starting subscription cleanup'); let subscriptions = await this.getActiveSubscriptions(accessToken); if (filter) { subscriptions = subscriptions.filter(filter); } result.totalFound = subscriptions.length; if (subscriptions.length === 0) { this.logger.log('No subscriptions found to clean up'); return result; } this.logger.log(`Found ${subscriptions.length} subscription(s) to delete`); for (const subscription of subscriptions) { try { await this.deleteSubscription(subscription.id, accessToken); result.successfullyDeleted++; result.deletedSubscriptionIds.push(subscription.id); } catch (deleteError) { const message = deleteError instanceof Error ? deleteError.message : 'Unknown error'; result.failedToDelete++; result.errors.push({ subscriptionId: subscription.id, error: deleteError instanceof Error ? deleteError.message : 'Unknown error', }); this.logger.warn(`โš ๏ธ Failed to delete subscription ${subscription.id}: ${message}`); } } this.logger.log(`๐Ÿ—‘๏ธ Cleanup completed: ${result.successfullyDeleted} deleted, ${result.failedToDelete} failed`); } catch (error) { const message = error instanceof Error ? error.message : 'Unknown error'; this.logger.error(`โŒ Cleanup operation failed: ${message}`); throw error; } return result; } async cleanupSubscriptionsForClient(clientId, accessToken) { this.logger.log(`๐Ÿงน Cleaning up subscriptions for client ${clientId}`); return this.cleanupSubscriptions({ accessToken, filter: (sub) => { var _a; return ((_a = sub.clientState) === null || _a === void 0 ? void 0 : _a.includes(`client_${clientId}_`)) || false; }, }); } async cleanupSubscriptionsForUser(userId, accessToken) { this.logger.log(`๐Ÿงน Cleaning up subscriptions for user ${userId}`); return this.cleanupSubscriptions({ accessToken, filter: (sub) => { var _a; return ((_a = sub.clientState) === null || _a === void 0 ? void 0 : _a.includes(`user_${userId}_`)) || false; }, }); } async revokeTokens(refreshToken) { try { if (!refreshToken) { this.logger.warn('โš ๏ธ No refresh token available for revocation'); return; } await axios_1.default.post(`${this.msAuthUrl}/logout`, new URLSearchParams({ token: refreshToken, token_type_hint: 'refresh_token', }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, timeout: 10000, }); this.logger.log('โœ… Microsoft tokens revoked successfully'); } catch (error) { const message = error instanceof Error ? error.message : 'Unknown error'; this.logger.warn(`โš ๏ธ Failed to revoke Microsoft tokens: ${message}`); } } async fullCleanup(refreshToken, accessToken, filter) { this.logger.log('๐Ÿ”„ Starting full cleanup (tokens + subscriptions)'); const result = await this.cleanupSubscriptions({ accessToken, filter, }); await this.revokeTokens(refreshToken); this.logger.log('โœ… Full cleanup completed'); return result; } }; exports.MicrosoftSubscriptionService = MicrosoftSubscriptionService; exports.MicrosoftSubscriptionService = MicrosoftSubscriptionService = MicrosoftSubscriptionService_1 = __decorate([ (0, common_1.Injectable)() ], MicrosoftSubscriptionService); //# sourceMappingURL=microsoft-subscription.service.js.map