| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- /**
- * @node crypto
- * @name Crypto
- * @category crypto
- * @version 1.0.0
- * @description Hash data, generate HMACs, and perform cryptographic operations for data integrity and message authentication
- * @icon lock
- */
- const configSchema = {
- type: 'object',
- properties: {
- operation: {
- type: 'string',
- title: 'Operation',
- enum: ['hash', 'hmac', 'random', 'encrypt', 'decrypt'],
- enumLabels: ['Hash', 'HMAC', 'Random Generation', 'Encrypt (Coming Soon)', 'Decrypt (Coming Soon)'],
- default: 'hash',
- description: 'Cryptographic operation to perform'
- },
- algorithm: {
- type: 'string',
- title: 'Algorithm',
- enum: ['md5', 'sha1', 'sha256', 'sha384', 'sha512'],
- enumLabels: ['MD5', 'SHA-1', 'SHA-256', 'SHA-384', 'SHA-512'],
- default: 'sha256',
- description: 'Hash algorithm to use',
- showWhen: { field: 'operation', value: ['hash', 'hmac'] }
- },
- outputFormat: {
- type: 'string',
- title: 'Output Format',
- enum: ['hex', 'base64'],
- enumLabels: ['Hexadecimal', 'Base64'],
- default: 'hex',
- description: 'Format of the output hash or HMAC',
- showWhen: { field: 'operation', value: ['hash', 'hmac'] }
- },
- secretKey: {
- type: 'string',
- title: 'Secret Key',
- description: 'Secret key for HMAC generation. Supports {{variable}} interpolation.',
- showWhen: { field: 'operation', value: 'hmac' }
- },
- randomLength: {
- type: 'number',
- title: 'Random Bytes Length',
- default: 32,
- description: 'Number of random bytes to generate (1-1024)',
- showWhen: { field: 'operation', value: 'random' }
- },
- randomFormat: {
- type: 'string',
- title: 'Random Output Format',
- enum: ['hex', 'base64', 'uuid'],
- enumLabels: ['Hexadecimal', 'Base64', 'UUID v4'],
- default: 'hex',
- description: 'Format of the random output',
- showWhen: { field: 'operation', value: 'random' }
- }
- },
- required: ['operation']
- };
- const inputSchema = {
- type: 'object',
- properties: {
- data: {
- type: 'any',
- description: 'Data to hash or process. Can be a string or will be JSON stringified.'
- },
- secretKey: {
- type: 'string',
- description: 'Override secret key for HMAC from input'
- }
- }
- };
- const outputSchema = {
- type: 'object',
- properties: {
- result: {
- type: 'string',
- description: 'The cryptographic operation result'
- },
- algorithm: {
- type: 'string',
- description: 'Algorithm used for the operation'
- },
- operation: {
- type: 'string',
- description: 'Operation that was performed'
- },
- format: {
- type: 'string',
- description: 'Output format (hex or base64)'
- },
- inputLength: {
- type: 'number',
- description: 'Length of the input data in bytes'
- }
- }
- };
- function interpolate(template, data) {
- if (typeof template !== 'string') return template;
- return template.replace(/\{\{([^}]+)\}\}/g, (match, key) => {
- const keys = key.trim().split('.');
- let value = data;
- for (const k of keys) {
- if (value && typeof value === 'object' && k in value) {
- value = value[k];
- } else {
- return match;
- }
- }
- return value !== undefined ? String(value) : match;
- });
- }
- async function execute(config, input, context) {
- const operation = config.operation || 'hash';
- if (operation === 'encrypt' || operation === 'decrypt') {
- throw new Error('Encrypt and Decrypt operations are not yet implemented. Coming soon.');
- }
- if (operation === 'random') {
- const format = config.randomFormat || 'hex';
- if (format === 'uuid') {
- const uuid = smartbotic.crypto.randomUUID();
- smartbotic.log.info('Generated random UUID');
- return {
- result: uuid,
- operation: 'random',
- format: 'uuid'
- };
- }
- const length = config.randomLength || 32;
- if (length < 1 || length > 1024) {
- throw new Error('Random length must be between 1 and 1024');
- }
- const randomHex = smartbotic.crypto.randomBytes(length);
- let result = randomHex;
- if (format === 'base64') {
- let binary = '';
- for (let i = 0; i < randomHex.length; i += 2) {
- binary += String.fromCharCode(parseInt(randomHex.substr(i, 2), 16));
- }
- result = smartbotic.utils.base64Encode(binary);
- }
- smartbotic.log.info('Generated ' + length + ' random bytes in ' + format + ' format');
- return {
- result: result,
- operation: 'random',
- format: format,
- inputLength: length
- };
- }
- const inputData = input.data !== undefined ? input.data : input;
- let dataStr;
- if (typeof inputData === 'string') {
- dataStr = inputData;
- } else if (inputData === null || inputData === undefined) {
- throw new Error('No data provided for ' + operation + ' operation');
- } else {
- dataStr = JSON.stringify(inputData);
- }
- const algorithm = config.algorithm || 'sha256';
- const outputFormat = config.outputFormat || 'hex';
- if (operation === 'hash') {
- smartbotic.log.info('Hashing ' + dataStr.length + ' bytes with ' + algorithm.toUpperCase());
- const result = smartbotic.crypto.hash(dataStr, algorithm, outputFormat);
- return {
- result: result,
- algorithm: algorithm,
- operation: 'hash',
- format: outputFormat,
- inputLength: dataStr.length
- };
- }
- if (operation === 'hmac') {
- let secretKey = input.secretKey || config.secretKey;
- if (secretKey && typeof secretKey === 'string') {
- secretKey = interpolate(secretKey, input);
- }
- if (!secretKey) {
- throw new Error('Secret key is required for HMAC operation');
- }
- smartbotic.log.info('Generating HMAC-' + algorithm.toUpperCase() + ' for ' + dataStr.length + ' bytes');
- const result = smartbotic.crypto.hmac(dataStr, secretKey, algorithm, outputFormat);
- return {
- result: result,
- algorithm: algorithm,
- operation: 'hmac',
- format: outputFormat,
- inputLength: dataStr.length
- };
- }
- throw new Error('Unknown operation: ' + operation);
- }
- module.exports = { configSchema, inputSchema, outputSchema, execute };
|