import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, NodeOperationError, } from 'n8n-workflow'; import { SecloreDRMFileService } from './Services/SecloreDRMFileService'; export class SecloreProtect implements INodeType { description: INodeTypeDescription = { displayName: 'Seclore Protect', name: 'secloreProtect', icon: 'file:SecloreProtect.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"]}}', description: 'Protect files using Seclore DRM with HotFolder configuration', defaults: { name: 'Seclore Protect', }, inputs: ['main'], outputs: ['main'], credentials: [ { name: 'secloreProtectApi', required: true, }, ], properties: [ { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, options: [ { name: 'Protect File with HotFolder', value: 'protectWithHotFolder', description: 'Protect a file using HotFolder ID configuration', action: 'Protect file with HotFolder', }, ], default: 'protectWithHotFolder', }, { displayName: 'HotFolder ID', name: 'hotfolderId', type: 'string', required: true, default: '', placeholder: 'e.g., hf-12345', description: 'The ID of the HotFolder configuration to use for protection', displayOptions: { show: { operation: ['protectWithHotFolder'], }, }, }, { displayName: 'Input Binary Property', name: 'binaryPropertyName', type: 'string', default: 'data', required: true, description: 'Name of the binary property that contains the file to protect', displayOptions: { show: { operation: ['protectWithHotFolder'], }, }, }, { displayName: 'Output Binary Property', name: 'outputBinaryPropertyName', type: 'string', default: 'data', required: true, description: 'Name of the binary property where the protected file will be stored', displayOptions: { show: { operation: ['protectWithHotFolder'], }, }, }, { displayName: 'Correlation ID', name: 'correlationId', type: 'string', default: '', placeholder: 'e.g., req-12345', description: 'Optional correlation ID for request tracking and logging', displayOptions: { show: { operation: ['protectWithHotFolder'], }, }, }, { displayName: 'Retry Count', name: 'retryCount', type: 'number', default: 3, description: 'Number of retry attempts for failed requests', displayOptions: { show: { operation: ['protectWithHotFolder'], }, }, }, ], }; async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); const returnData: INodeExecutionData[] = []; // Get credentials const credentials = await this.getCredentials('secloreProtectApi'); const baseUrl = credentials.baseUrl as string; const tenantId = credentials.tenantId as string; const tenantSecret = credentials.tenantSecret as string; // Initialize the file service const fileService = new SecloreDRMFileService( this, baseUrl, tenantId, tenantSecret ); // Get node parameters const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { try { if (operation === 'protectWithHotFolder') { // Get parameters for this item const hotfolderId = this.getNodeParameter('hotfolderId', i) as string; const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; const outputBinaryPropertyName = this.getNodeParameter('outputBinaryPropertyName', i) as string; const correlationId = this.getNodeParameter('correlationId', i) as string; const retryCount = this.getNodeParameter('retryCount', i) as number; // Validate required parameters if (!hotfolderId) { throw new NodeOperationError(this.getNode(), 'HotFolder ID is required', { itemIndex: i, }); } // Get input binary data const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const fileBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); // Upload the file first const uploadResult = await fileService.uploadFile( new Uint8Array(fileBuffer), binaryData.fileName || 'file', correlationId || undefined, retryCount ); // Protect the uploaded file with HotFolder const protectResult = await fileService.protectWithHotFolder( { hotfolderId, fileStorageId: uploadResult.fileStorageId, }, correlationId || undefined, retryCount ); // Download the protected file const protectedFileData = await fileService.downloadFile( protectResult.fileStorageId, correlationId || undefined, retryCount ); // Create output binary data const outputBinaryData = await this.helpers.prepareBinaryData( protectedFileData.buffer, binaryData.fileName || 'protected_file', binaryData.mimeType ); // Create return item with binary data and metadata const returnItem: INodeExecutionData = { json: { success: true, originalFileStorageId: uploadResult.fileStorageId, protectedFileStorageId: protectResult.fileStorageId, secloreFileId: protectResult.secloreFileId, hotfolderId, fileName: binaryData.fileName, fileSize: protectedFileData.length, correlationId: correlationId || null, }, binary: { [outputBinaryPropertyName]: outputBinaryData, }, }; returnData.push(returnItem); } } catch (error) { // Handle errors gracefully if (this.continueOnFail()) { const returnItem: INodeExecutionData = { json: { success: false, error: error.message, itemIndex: i, }, }; returnData.push(returnItem); } else { throw new NodeOperationError(this.getNode(), error.message, { itemIndex: i, }); } } } return [returnData]; } }