UNPKG

@socketsecurity/lib

Version:

Core utilities and infrastructure for Socket.dev security tools

367 lines (366 loc) 11.6 kB
import { z } from './zod'; // Define BufferEncoding type for TypeScript compatibility. type BufferEncoding = globalThis.BufferEncoding; /** * IPC handshake schema - used for initial connection establishment. * The handshake includes version info and authentication tokens. * @internal Exported for testing purposes. */ export declare const IpcHandshakeSchema: z.ZodObject<{ id: z.ZodString; timestamp: z.ZodNumber; type: z.ZodLiteral<"handshake">; data: z.ZodObject<{ version: z.ZodString; pid: z.ZodNumber; apiToken: z.ZodOptional<z.ZodString>; appName: z.ZodString; }, z.core.$strip>; }, z.core.$strip>; /** * TypeScript interfaces for IPC communication. * These types ensure type consistency across the IPC module. */ /** * Base IPC message interface. * All IPC messages must conform to this structure. */ export interface IpcMessage<T = unknown> { /** Unique identifier for message tracking and response correlation. */ id: string; /** Unix timestamp for freshness validation and replay prevention. */ timestamp: number; /** Message type identifier for routing and handling. */ type: string; /** Payload data - can be any JSON-serializable value. */ data: T; } /** * IPC handshake message interface. * Used for initial connection establishment. */ export interface IpcHandshake extends IpcMessage<{ /** Protocol version for compatibility checking. */ version: string; /** Process ID for identification. */ pid: number; /** Optional API token for authentication. */ apiToken?: string; /** Application name for multi-app support. */ appName: string; }> { type: 'handshake'; } /** * IPC stub file interface. * Represents the structure of stub files used for filesystem-based IPC. */ export interface IpcStub { /** Process ID that created the stub. */ pid: number; /** Creation timestamp for age validation. */ timestamp: number; /** The actual data payload. */ data: unknown; } /** * Options for IPC communication */ export interface IpcOptions { /** Timeout in milliseconds for async operations. */ timeout?: number; /** Text encoding for message serialization. */ encoding?: BufferEncoding; } /** * Create a unique IPC channel identifier for message correlation. * * Generates a unique identifier that combines: * - A prefix for namespacing (defaults to 'socket') * - The current process ID for process identification * - A random hex string for uniqueness * * @param prefix - Optional prefix to namespace the channel ID * @returns A unique channel identifier string * * @example * ```typescript * const channelId = createIpcChannelId('socket-cli') * // Returns: 'socket-cli-12345-a1b2c3d4e5f6g7h8' * ``` */ export declare function createIpcChannelId(prefix?: string): string; /** * Get the IPC stub path for a given application. * * This function generates a unique file path for IPC stub files that are used * to pass data between processes. The stub files are stored in a hidden directory * within the system's temporary folder. * * ## Path Structure: * - Base: System temp directory (e.g., /tmp on Unix, %TEMP% on Windows) * - Directory: `.socket-ipc/{appName}/` * - Filename: `stub-{pid}.json` * * ## Security Features: * - Files are isolated per application via appName parameter * - Process ID in filename prevents collisions between concurrent processes * - Temporary directory location ensures automatic cleanup on system restart * * @param appName - The application identifier (e.g., 'socket-cli', 'socket-dlx') * @returns Full path to the IPC stub file * * @example * ```typescript * const stubPath = getIpcStubPath('socket-cli') * // Returns: '/tmp/.socket-ipc/socket-cli/stub-12345.json' (Unix) * // Returns: 'C:\\Users\\Name\\AppData\\Local\\Temp\\.socket-ipc\\socket-cli\\stub-12345.json' (Windows) * ``` * * @used Currently used by socket-cli for self-update and inter-process communication */ export declare function getIpcStubPath(appName: string): string; /** * Write IPC data to a stub file for inter-process data transfer. * * This function creates a stub file containing data that needs to be passed * between processes. The stub file includes metadata like process ID and * timestamp for validation. * * ## File Structure: * ```json * { * "pid": 12345, * "timestamp": 1699564234567, * "data": { ... } * } * ``` * * ## Use Cases: * - Passing API tokens to child processes * - Transferring configuration between Socket CLI components * - Sharing large data that exceeds environment variable limits * * @param appName - The application identifier * @param data - The data to write to the stub file * @returns Promise resolving to the stub file path * * @example * ```typescript * const stubPath = await writeIpcStub('socket-cli', { * apiToken: 'secret-token', * config: { ... } * }) * // Pass stubPath to child process for reading * ``` */ export declare function writeIpcStub(appName: string, data: unknown): Promise<string>; /** * Read IPC data from a stub file with automatic cleanup. * * This function reads data from an IPC stub file and validates its freshness. * Stale files (older than 5 minutes) are automatically cleaned up to prevent * accumulation of temporary files. * * ## Validation Steps: * 1. Read and parse JSON file * 2. Validate structure with Zod schema * 3. Check timestamp freshness * 4. Clean up if stale * 5. Return data if valid * * @param stubPath - Path to the stub file to read * @returns Promise resolving to the data or null if invalid/stale * * @example * ```typescript * const data = await readIpcStub('/tmp/.socket-ipc/socket-cli/stub-12345.json') * if (data) { * console.log('Received:', data) * } * ``` * * @unused Reserved for future implementation */ export declare function readIpcStub(stubPath: string): Promise<unknown>; /** * Clean up IPC stub files for an application. * * This maintenance function removes stale IPC stub files to prevent * accumulation in the temporary directory. It's designed to be called * periodically or on application startup. * * ## Cleanup Rules: * - Files older than 5 minutes are removed (checked via both filesystem mtime and JSON timestamp) * - Only stub files (stub-*.json) are processed * - Errors are silently ignored (best-effort cleanup) * * @param appName - The application identifier * @returns Promise that resolves when cleanup is complete * * @example * ```typescript * // Clean up on application startup * await cleanupIpcStubs('socket-cli') * ``` * * @unused Reserved for future implementation */ export declare function cleanupIpcStubs(appName: string): Promise<void>; /** * Send data through Node.js IPC channel. * * This function sends structured messages through the Node.js IPC channel * when available. The IPC channel must be established with stdio: ['pipe', 'pipe', 'pipe', 'ipc']. * * ## Requirements: * - Process must have been spawned with IPC channel enabled * - Message must be serializable to JSON * - Process.send() must be available * * @param process - The process object with IPC channel * @param message - The IPC message to send * @returns true if message was sent, false otherwise * * @example * ```typescript * const message = createIpcMessage('handshake', { version: '1.0.0' }) * const sent = sendIpc(childProcess, message) * ``` * * @unused Reserved for bidirectional communication implementation */ export declare function sendIpc(process: NodeJS.Process | unknown, message: IpcMessage): boolean; /** * Receive data through Node.js IPC channel. * * Sets up a listener for IPC messages with automatic validation and parsing. * Returns a cleanup function to remove the listener when no longer needed. * * ## Message Flow: * 1. Receive raw message from IPC channel * 2. Validate with parseIpcMessage * 3. Call handler if valid * 4. Ignore invalid messages * * @param handler - Function to call with valid IPC messages * @returns Cleanup function to remove the listener * * @example * ```typescript * const cleanup = onIpc((message) => { * console.log('Received:', message.type, message.data) * }) * // Later... * cleanup() // Remove listener * ``` * * @unused Reserved for bidirectional communication */ export declare function onIpc(handler: (message: IpcMessage) => void): () => void; /** * Create a promise that resolves when a specific IPC message is received. * * This utility function provides async/await support for IPC communication, * allowing you to wait for specific message types with timeout support. * * ## Features: * - Automatic timeout handling * - Type-safe message data * - Resource cleanup on completion * - Promise-based API * * @param messageType - The message type to wait for * @param options - Options including timeout configuration * @returns Promise resolving to the message data * * @example * ```typescript * try { * const response = await waitForIpc<ConfigData>('config-response', { * timeout: 5000 // 5 seconds * }) * console.log('Config received:', response) * } catch (error) { * console.error('Timeout waiting for config') * } * ``` * * @unused Reserved for request-response pattern implementation */ export declare function waitForIpc<T = unknown>(messageType: string, options?: IpcOptions): Promise<T>; /** * Create an IPC message with proper structure and metadata. * * This factory function creates properly structured IPC messages with: * - Unique ID for tracking * - Timestamp for freshness * - Type for routing * - Data payload * * @param type - The message type identifier * @param data - The message payload * @returns A properly structured IPC message * * @example * ```typescript * const handshake = createIpcMessage('handshake', { * version: '1.0.0', * pid: process.pid, * appName: 'socket-cli' * }) * ``` * * @unused Reserved for future message creation needs */ export declare function createIpcMessage<T = unknown>(type: string, data: T): IpcMessage<T>; /** * Check if process has IPC channel available. * * This utility checks whether a process object has the necessary * properties for IPC communication. Used to determine if IPC * messaging is possible before attempting to send. * * @param process - The process object to check * @returns true if IPC is available, false otherwise * * @example * ```typescript * if (hasIpcChannel(childProcess)) { * sendIpc(childProcess, message) * } else { * // Fall back to alternative communication method * } * ``` * * @unused Reserved for IPC availability detection */ export declare function hasIpcChannel(process: unknown): boolean; /** * Safely parse and validate IPC messages. * * This function performs runtime validation of incoming messages * to ensure they conform to the IPC message structure. It uses * Zod schemas for robust validation. * * ## Validation Steps: * 1. Check if message is an object * 2. Validate required fields exist * 3. Validate field types * 4. Return typed message or null * * @param message - The raw message to parse * @returns Parsed IPC message or null if invalid * * @example * ```typescript * const parsed = parseIpcMessage(rawMessage) * if (parsed) { * handleMessage(parsed) * } * ``` * * @unused Reserved for message validation needs */ export declare function parseIpcMessage(message: unknown): IpcMessage | null; export {};