@socketsecurity/lib
Version:
Core utilities and infrastructure for Socket.dev security tools
367 lines (366 loc) • 11.6 kB
TypeScript
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 {};