UNPKG

bws-secure

Version:

Secure environment management with Bitwarden Secrets Manager

230 lines (201 loc) 7.86 kB
#!/usr/bin/env node import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import dotenv from 'dotenv'; // Get the directory name in ESM const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Configure dotenv with better path resolution const possibleEnvPaths = [ path.join(process.cwd(), '.env'), // Root directory path.join(__dirname, '../../.env'), // Two levels up path.join(__dirname, '../.env'), // One level up path.join(__dirname, '.env') // Same directory ]; // Try to find the first existing .env file const envPath = possibleEnvPaths.find((path) => fs.existsSync(path)); if (envPath) { console.log(`\x1b[36mLoading .env from:\x1b[0m ${envPath}`); dotenv.config({ path: envPath }); } else { console.log('\x1b[33mNo .env file found in common locations. Using process.env directly.\x1b[0m'); // Still call config() to ensure dotenv is initialized dotenv.config(); } // Log environment loading status console.log('\x1b[32mEnvironment Status:\x1b[0m', { NODE_ENV: process.env.NODE_ENV || 'not set', NETLIFY: process.env.NETLIFY ? 'true' : 'false', VERCEL: process.env.VERCEL ? '1' : '0', ENV_PATH: envPath || 'using process.env', VARS_COUNT: Object.keys(process.env).length }); console.log('Available Environment Variables:', Object.keys(process.env).length); console.log('Sample Variable:', process.env.BWS_SECRET_TEST_VAR); // To verify .env loading // Array of important variables to check const IMPORTANT_VARS = ['BWS_SECRET_TEST_VAR']; // Log the values of important variables console.log('\x1b[33mImportant Variables Values:\x1b[0m'); IMPORTANT_VARS.forEach((varName) => { console.log(`${varName}: "${process.env[varName]}"`); }); // Function to safely display environment variables const sanitizeEnvValue = (value) => { if (!value) return 'NOT SET'; return value; // Remove sanitization to show full values }; // Get all environment variables in a structured format const getAllEnvVars = () => { // Return the complete process.env object return Object.fromEntries( Object.entries(process.env) .sort(([a], [b]) => a.localeCompare(b)) .map(([key, value]) => [key, sanitizeEnvValue(value)]) ); }; // Generate status indicators for important variables const generateStatusIndicators = () => { return IMPORTANT_VARS.map( (varName) => ` <div class="status ${process.env[varName] ? 'success' : 'error'}"> ${varName}: ${process.env[varName] ? 'Available ✓' : 'Not Available ✗'} <br> <span class="env-value">Value: ${process.env[varName] || 'undefined'}</span> </div> ` ).join('\n'); }; // Update the getDirectoryStructure function to handle permissions better const getDirectoryStructure = (startPath, depth = 3) => { if (depth < 0) return null; if (!fs.existsSync(startPath)) return `Directory does not exist: ${startPath}`; const structure = {}; try { const items = fs.readdirSync(startPath, { withFileTypes: true }); for (const item of items) { const itemPath = path.join(startPath, item.name); try { if (item.isDirectory()) { structure[item.name + '/'] = depth > 0 ? getDirectoryStructure(itemPath, depth - 1) : '...'; } else if (item.isSymbolicLink()) { const linkTarget = fs.readlinkSync(itemPath); structure[item.name] = `-> ${linkTarget}`; } else { structure[item.name] = null; } } catch (itemError) { structure[item.name] = `<access denied: ${itemError.code}>`; } } } catch (error) { return `<error reading directory: ${error.code}>`; } return structure; }; // Update buildInfo to include more system directories const buildInfo = { NODE_ENV: process.env.NODE_ENV, BUILD_TIME: new Date().toISOString(), PLATFORM: process.platform, ARCHITECTURE: process.arch, NODE_VERSION: process.version, PROCESS_ID: process.pid, PROCESS_TITLE: process.title, PROCESS_UPTIME: process.uptime(), MEMORY_USAGE: process.memoryUsage(), CPU_USAGE: process.cpuUsage(), CURRENT_DIR: process.cwd(), EXECUTABLE_PATH: process.execPath, // Add these new properties ROOT_DIRECTORY: getDirectoryStructure('/'), HOME_DIRECTORY: getDirectoryStructure(process.env.HOME), CURRENT_DIRECTORY: getDirectoryStructure(process.cwd()), SYSTEM_DIRECTORIES: { 'Root (/)': getDirectoryStructure('/', 1), 'Opt (/opt)': getDirectoryStructure('/opt', 2), 'Build (/opt/build)': getDirectoryStructure('/opt/build', 2), 'BuildHome (/opt/buildhome)': getDirectoryStructure('/opt/buildhome', 2), 'Current Directory': getDirectoryStructure(process.cwd(), 2) }, PROCESS_INFO: { NODE_ENV: process.env.NODE_ENV, BUILD_TIME: new Date().toISOString(), PLATFORM: process.platform, ARCHITECTURE: process.arch, NODE_VERSION: process.version, PROCESS_ID: process.pid, PROCESS_TITLE: process.title, PROCESS_UPTIME: process.uptime(), MEMORY_USAGE: process.memoryUsage(), CPU_USAGE: process.cpuUsage(), CURRENT_DIR: process.cwd(), EXECUTABLE_PATH: process.execPath } }; // Create HTML content with injected environment variables const htmlContent = `<!DOCTYPE html> <html> <head> <title>Build Environment Debug</title> <style> body { margin: 0; padding: 20px; background: #1a1a1a; color: #fff; font-family: monospace; } .container { background: #2a2a2a; padding: 20px; border-radius: 8px; } pre { background: #333; padding: 15px; border-radius: 4px; overflow-x: auto; } .status { padding: 8px 16px; border-radius: 4px; display: inline-block; margin-right: 10px; margin-bottom: 10px; } .success { background: #1b5e20; } .error { background: #b71c1c; } .env-var { margin: 5px 0; } .env-key { color: #66bb6a; } .env-value { color: #90caf9; } .status-container { margin-bottom: 20px; } </style> </head> <body> <div class="container"> <h1>Build Environment Debug</h1> <h3>Generated at: ${new Date().toISOString()}</h3> <h2>Critical Variables Status</h2> <div class="status-container"> ${generateStatusIndicators()} </div> <h2>Environment Summary</h2> <div class="status ${Object.keys(process.env).length > 0 ? 'success' : 'error'}"> Total Environment Variables: ${Object.keys(process.env).length} </div> <h2>All Environment Variables</h2> <pre>${JSON.stringify(getAllEnvVars(), null, 2)}</pre> <h2>Process Information</h2> <pre>${JSON.stringify(buildInfo.PROCESS_INFO, null, 2)}</pre> <h2>System Directory Structure</h2> <pre>${JSON.stringify(buildInfo.SYSTEM_DIRECTORIES, null, 2)}</pre> </div> </body> </html>`; // Update the public directory path to ensure it works with Netlify const publicDir = process.env.NETLIFY ? path.join(process.cwd(), 'public') : path.join(__dirname, '../../public'); // Add more detailed logging console.log(`\x1b[34mCreating public directory at:\x1b[0m ${publicDir}`); if (!fs.existsSync(publicDir)) { console.log(`Public directory doesn't exist, creating it...`); fs.mkdirSync(publicDir, { recursive: true }); console.log(`✓ Created public directory`); } // Write the file with more detailed logging const outputPath = path.join(publicDir, 'index.html'); console.log(`\x1b[32mWriting debug information to:\x1b[0m ${outputPath}`); fs.writeFileSync(outputPath, htmlContent); console.log(`\x1b[32m✓ Successfully generated index.html at:\x1b[0m ${outputPath}`); console.log(`\x1b[35mFound ${Object.keys(process.env).length} environment variables\x1b[0m`); console.log(`\x1b[36mFile size: ${(fs.statSync(outputPath).size / 1024).toFixed(2)}KB\x1b[0m`);