import { Duplex } from "node:stream"; import GRPCClient from "./GRPCClient"; import { type DecryptRequest, type EncryptRequest } from "../../../types/crypto/Requests"; import IClientCrypto from "../../../interfaces/Client/IClientCrypto"; /** * gRPC-based cryptography building block implementation. * * Provides encryption and decryption operations via the Dapr sidecar. * Supports streaming for large payloads and both synchronous and streaming APIs. * * Uses gRPC bidirectional streaming for efficient chunked data processing. * Supports multiple cryptographic algorithms configured in the Dapr sidecar. * * @implements {IClientCrypto} * @see {@link https://docs.dapr.io/reference/api/cryptography_api/} Dapr Cryptography API * @see {@link DaprClient.crypto} for unified API * * @internal */ export default class GRPCClientCrypto implements IClientCrypto { /** * Reference to the underlying gRPC client. */ client: GRPCClient; /** * Creates a gRPC cryptography building block. * * @param client - The gRPC client instance */ constructor(client: GRPCClient); /** * Encrypts data or returns a duplex stream for streaming encryption. * * **Overload 1:** With data argument - encrypts buffer and returns encrypted Buffer * **Overload 2:** Without data - returns a Duplex stream for streaming encryption * * Uses chunked streaming internally for efficient processing of large payloads. * The key wrapping algorithm and encryption cipher are specified in options. * * @overload * @param opts - Encryption options (keyName, componentName, keyWrapAlgorithm required) * @returns Promise resolving to a Duplex stream for streaming encryption * * @overload * @param inData - Data to encrypt (Buffer, ArrayBuffer, ArrayBufferView, or string) * @param opts - Encryption options (keyName, componentName, keyWrapAlgorithm required) * @returns Promise resolving to encrypted Buffer * * @throws Rejects if required options are missing or encryption fails * * @example * ```typescript * // Encrypt a buffer * const encrypted = await client.crypto.encrypt( * Buffer.from("secret data"), * { * componentName: "myencryptor", * keyName: "mykey", * keyWrapAlgorithm: "RSA" * } * ); * * // Stream large file * const stream = await client.crypto.encrypt({ * componentName: "myencryptor", * keyName: "mykey", * keyWrapAlgorithm: "RSA" * }); * fs.createReadStream("largefile").pipe(stream).pipe(fs.createWriteStream("encrypted")); * ``` * * @see {@link decrypt} * @see {@link https://docs.dapr.io/reference/api/cryptography_api/#encrypt} */ encrypt(opts: EncryptRequest): Promise; encrypt(inData: Buffer | ArrayBuffer | ArrayBufferView | string, opts: EncryptRequest): Promise; /** * Decrypts data or returns a duplex stream for streaming decryption. * * **Overload 1:** With data argument - decrypts buffer and returns decrypted Buffer * **Overload 2:** Without data - returns a Duplex stream for streaming decryption * * Uses chunked streaming internally for efficient processing of large payloads. * The cryptographic key and component name are specified in options. * * @overload * @param opts - Decryption options (componentName required; keyName optional) * @returns Promise resolving to a Duplex stream for streaming decryption * * @overload * @param inData - Encrypted data to decrypt (Buffer, ArrayBuffer, ArrayBufferView) * @param opts - Decryption options (componentName required; keyName optional) * @returns Promise resolving to decrypted Buffer * * @throws Rejects if options are invalid or decryption fails * * @example * ```typescript * // Decrypt a buffer * const decrypted = await client.crypto.decrypt( * encryptedBuffer, * { * componentName: "myencryptor", * keyName: "mykey" * } * ); * * // Stream large file * const stream = await client.crypto.decrypt({ * componentName: "myencryptor", * keyName: "mykey" * }); * fs.createReadStream("encrypted").pipe(stream).pipe(fs.createWriteStream("decrypted")); * ``` * * @see {@link encrypt} * @see {@link https://docs.dapr.io/reference/api/cryptography_api/#decrypt} */ decrypt(opts: DecryptRequest): Promise; decrypt(inData: Buffer | ArrayBuffer | ArrayBufferView, opts: DecryptRequest): Promise; /** * Converts various input types to a Buffer. * * @private * @param inData - Input data to convert (string, Buffer, ArrayBuffer, ArrayBufferView) * @returns The data as a Buffer * * @throws Throws if input type is invalid * * @internal */ private toArrayBuffer; /** * Handles stream completion when data is provided. * * If inData is provided, buffers all output chunks and returns a resolved Buffer. * If inData is not provided, returns the duplex stream for manual handling. * * @private * @param duplexStream - The DaprChunkedStream instance * @param inData - Optional input data (if provided, stream is buffered) * @returns Promise resolving to either a Duplex stream or completed Buffer * * @internal */ private processStream; }