import { forwardRef, Inject, Injectable } from '@nestjs/common'; import { Integration } from '@prisma/client'; import { IntegrationManager } from '@gitroom/nestjs-libraries/integrations/integration.manager'; import { IntegrationService } from '@gitroom/nestjs-libraries/database/prisma/integrations/integration.service'; import { AuthTokenDetails, SocialProvider, } from '@gitroom/nestjs-libraries/integrations/social/social.integrations.interface'; @Injectable() export class RefreshIntegrationService { constructor( private _integrationManager: IntegrationManager, @Inject(forwardRef(() => IntegrationService)) private _integrationService: IntegrationService ) {} async refresh(integration: Integration): Promise { const socialProvider = this._integrationManager.getSocialIntegration( integration.providerIdentifier ); const refresh = await this.refreshProcess(integration, socialProvider); if (!refresh) { return false as const; } await this._integrationService.createOrUpdateIntegration( undefined, !!socialProvider.oneTimeToken, integration.organizationId, integration.name, integration.picture!, 'social', integration.internalId, integration.providerIdentifier, refresh.accessToken, refresh.refreshToken, refresh.expiresIn ); return refresh; } private async refreshProcess( integration: Integration, socialProvider: SocialProvider ): Promise { const refresh: false | AuthTokenDetails = await socialProvider .refreshToken(integration.refreshToken) .catch((err) => false); if (!refresh) { await this._integrationService.refreshNeeded( integration.organizationId, integration.id ); await this._integrationService.informAboutRefreshError( integration.organizationId, integration ); await this._integrationService.disconnectChannel(integration.organizationId, integration); return false; } if (!socialProvider.reConnect) { return refresh; } const reConnect = await socialProvider.reConnect( integration.rootInternalId, integration.internalId, refresh.accessToken ); return { ...refresh, ...reConnect, }; } }