diff --git a/package.json b/package.json index 4bba7fa..afb9e0d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@erp/plugin-sdk", - "version": "1.10.1", + "version": "1.10.2", "main": "dist/index.js", "types": "dist/index.d.ts", "bin": { diff --git a/src/backend/services/core.service.ts b/src/backend/services/core.service.ts index 8597272..17ddd51 100644 --- a/src/backend/services/core.service.ts +++ b/src/backend/services/core.service.ts @@ -3,6 +3,7 @@ import { ClientProxy } from '@nestjs/microservices'; import { firstValueFrom, timeout as rxTimeout } from 'rxjs'; import { SystemEvent } from '../interfaces/communication'; import { v4 as uuidv4 } from 'uuid'; +import * as crypto from 'crypto'; import * as fs from 'fs'; import * as path from 'path'; import * as amqp from 'amqplib'; @@ -167,6 +168,35 @@ export class CoreService { }); } + async callAsService(pluginId: string, path: string, body?: any): Promise { + const registrationKey = process.env.REGISTRATION_KEY || ''; + if (!registrationKey) { + throw new Error('REGISTRATION_KEY not configured — cannot make service-to-service call'); + } + const payload = JSON.stringify({ + pluginId, + path: path.replace(/^\//, ''), + timestamp: Date.now(), + body: body !== undefined ? body : null, + }); + const signature = crypto.createHmac('sha256', registrationKey).update(payload).digest('hex'); + const encoded = Buffer.from(payload).toString('base64'); + const serviceAuth = `v1.${encoded}.${signature}`; + + const coreUrl = process.env.CORE_BACKEND_URL || 'http://localhost:3001'; + const response = await fetch(`${coreUrl}/api/plugins/rpc/${pluginId}/${path.replace(/^\//, '')}`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', 'X-Service-Auth': serviceAuth }, + body: body !== undefined ? JSON.stringify(body) : undefined, + }); + if (!response.ok) { + const text = await response.text().catch(() => response.statusText); + throw new Error(`Service call to ${pluginId}/${path} failed: ${response.status} ${text}`); + } + const text = await response.text(); + try { return JSON.parse(text); } catch { return text as any; } + } + async discoverPlugins(): Promise { try { const response = await this.fetchCore('/api/plugins/discovery');