UNPKG

vaultace-cli

Version:

AI-powered security scanner that detects vulnerabilities in AI-generated code. Proactive scanning, autonomous fixing, and emergency response for modern development teams.

205 lines (167 loc) 4.87 kB
/** * Configuration Manager * Handles CLI configuration storage and retrieval */ const fs = require('fs-extra') const path = require('path') const os = require('os') class ConfigManager { static getConfigPath() { // Use XDG config directory or fallback to home const configDir = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config') return path.join(configDir, 'vaultace', 'config.json') } static getConfig() { try { const configPath = this.getConfigPath() if (!fs.existsSync(configPath)) { return this.getDefaultConfig() } const config = fs.readJsonSync(configPath) // Merge with defaults to ensure all keys exist return { ...this.getDefaultConfig(), ...config } } catch (error) { console.warn(`Config read error: ${error.message}`) return this.getDefaultConfig() } } static getDefaultConfig() { return { apiUrl: 'https://api.vaultace.co', auth: { accessToken: null, refreshToken: null, expiresAt: null }, defaults: { severity: 'medium', format: 'table', aiPatterns: true, respectGitignore: true }, preferences: { autoUpdate: true, verbose: false, colorOutput: true } } } static saveConfig(config) { try { const configPath = this.getConfigPath() // Ensure config directory exists fs.ensureDirSync(path.dirname(configPath)) // Write config with proper permissions fs.writeJsonSync(configPath, config, { spaces: 2, mode: 0o600 }) } catch (error) { throw new Error(`Failed to save config: ${error.message}`) } } static set(key, value) { const config = this.getConfig() // Handle nested keys (e.g., "defaults.severity") const keys = key.split('.') let current = config for (let i = 0; i < keys.length - 1; i++) { const k = keys[i] if (!current[k] || typeof current[k] !== 'object') { current[k] = {} } current = current[k] } current[keys[keys.length - 1]] = value this.saveConfig(config) } static get(key) { const config = this.getConfig() // Handle nested keys const keys = key.split('.') let current = config for (const k of keys) { if (current && typeof current === 'object' && k in current) { current = current[k] } else { return undefined } } return current } static setAuth(authData) { const config = this.getConfig() config.auth = { ...config.auth, ...authData } this.saveConfig(config) } static clearAuth() { const config = this.getConfig() config.auth = { accessToken: null, refreshToken: null, expiresAt: null } this.saveConfig(config) } static isAuthenticated() { const config = this.getConfig() return !!(config.auth?.accessToken && config.auth?.refreshToken) } static isTokenExpired() { const config = this.getConfig() if (!config.auth?.expiresAt) { return true } // Add 5 minute buffer for token refresh return Date.now() > (config.auth.expiresAt - 300000) } static reset() { const defaultConfig = this.getDefaultConfig() this.saveConfig(defaultConfig) } static validateConfig(config = null) { const cfg = config || this.getConfig() // Validate API URL if (cfg.apiUrl) { try { new URL(cfg.apiUrl) } catch { throw new Error('Invalid API URL format') } } // Validate severity levels const validSeverities = ['low', 'medium', 'high', 'critical'] if (cfg.defaults?.severity && !validSeverities.includes(cfg.defaults.severity)) { throw new Error(`Invalid severity level. Must be one of: ${validSeverities.join(', ')}`) } // Validate output formats const validFormats = ['table', 'json', 'csv', 'sarif'] if (cfg.defaults?.format && !validFormats.includes(cfg.defaults.format)) { throw new Error(`Invalid output format. Must be one of: ${validFormats.join(', ')}`) } return true } // Migration helpers static migrate() { try { const config = this.getConfig() let migrated = false // Example migration: rename old keys if (config.api_url) { config.apiUrl = config.api_url delete config.api_url migrated = true } if (migrated) { this.saveConfig(config) console.log(chalk.blue('ℹ️ Configuration migrated to latest format')) } } catch (error) { console.warn(`Config migration warning: ${error.message}`) } } } module.exports = ConfigManager