import { Injectable, Logger } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; import { ConfigService } from '@nestjs/config'; import { publicEncrypt, constants } from 'crypto'; import { firstValueFrom } from 'rxjs'; @Injectable() export class ExternalServicesService { private readonly logger = new Logger(ExternalServicesService.name); private readonly publicKey: string; private readonly coreApiUrl: string; constructor( private readonly httpService: HttpService, private readonly configService: ConfigService, ) { const b64Key = this.configService.get('RSA_PUBLIC_KEY_BASE64'); if (b64Key) { try { this.publicKey = Buffer.from(b64Key, 'base64').toString('utf-8'); } catch (e) { this.logger.error('Failed to decode RSA Public Key', e); } } else { this.logger.warn('RSA_PUBLIC_KEY_BASE64 is missing'); } this.coreApiUrl = this.configService.get('CORE_API_URL') || 'http://localhost:8521'; } async saveStripeKey(rawSecret: string, authHeader: string) { if (!this.publicKey) { throw new Error('RSA Public Key is not configured in Backoffice'); } try { const encrypted = publicEncrypt( { key: this.publicKey, padding: constants.RSA_PKCS1_OAEP_PADDING, oaepHash: 'sha256', }, Buffer.from(rawSecret, 'utf-8') ); const encryptedBase64 = encrypted.toString('base64'); // Send to Core API const response = await firstValueFrom( this.httpService.post( `${this.coreApiUrl}/api/v1/system/credentials`, { serviceName: 'stripe', encryptedPayload: encryptedBase64, }, { headers: { Authorization: authHeader, }, } ) ); return response.data; } catch (error) { this.logger.error('Failed to save Stripe key', error); throw error; } } }