apiveritas
Version:
Lightweight CLI tool for consumer-driven API contract testing via JSON schema and payload comparisons.
70 lines (61 loc) • 2.71 kB
text/typescript
/**
* @file PathValidator.
* @author Mario Galea
* @description
* Provides safety checks and resolution logic for user-specified folder paths.
* Ensures configuration paths are not empty, malformed, or pointing to sensitive system directories.
* This module protects against accidental misconfiguration that could overwrite or access critical files.
*/
import path from 'path';
/**
* PathValidator validates folder paths used in the ApiVeritas config.
* It prevents the use of dangerous or inappropriate system paths and ensures
* that all folder paths used in the tool are safe and well-formed.
*/
export class PathValidator {
/**
* List of system-critical root paths considered unsafe to write into or use as output folders.
*/
private static riskyRoots = ['/', '/etc', '/bin', '/boot', '/sys', '/proc'];
/**
* Determines if the given path is suspicious and potentially harmful (e.g., a system directory).
* This prevents users from accidentally targeting critical areas of the filesystem.
*
* @param {string} p - Path to evaluate
* @returns {boolean} True if the path is deemed risky
*/
static isSuspiciousPath(p: string): boolean {
const normalized = path.resolve(p).toLowerCase();
return this.riskyRoots.some(root =>
normalized === root || normalized.startsWith(root + path.sep)
);
}
/**
* Validates and resolves a folder path from the configuration.
* If the path is empty, undefined, or suspicious, a fallback path is used instead.
* Logs a warning when falling back, if a logger is provided.
*
* @param {string | undefined} folderPath - The path string provided by the user (relative or absolute)
* @param {string} fallbackPath - The default path to use if validation fails
* @param {string} label - Label used in logging to identify the setting (e.g., "payloadsPath")
* @param {{ warn: (msg: string) => void }} [logger] - Optional logger with a `warn` method
* @returns {string} A safe and validated absolute path
*/
static validateFolderPath(
folderPath: string | undefined,
fallbackPath: string,
label: string,
logger?: { warn: (msg: string) => void }
): string {
if (!folderPath || folderPath.trim() === '') {
logger?.warn(`Config: ${label} not set or empty. Using default: ${fallbackPath}`);
return fallbackPath;
}
const resolved = path.resolve(folderPath);
if (this.isSuspiciousPath(resolved)) {
logger?.warn(`Config: ${label} path "${resolved}" is suspicious or unsafe. Using default: ${fallbackPath}`);
return fallbackPath;
}
return resolved;
}
}