@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
JavaScript
;
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