cube-ms
Version:
Production-ready microservice framework with health monitoring, validation, error handling, and Docker Swarm support
258 lines (207 loc) ⢠8.34 kB
JavaScript
/**
* Setup .npmrc for CCN Platform Registry
*
* This script helps developers setup .npmrc with their own token
* to avoid token expiration issues in version control.
*/
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import readline from 'readline';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const colors = {
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m',
reset: '\x1b[0m',
bold: '\x1b[1m'
};
function log(message, color = colors.reset) {
console.log(`${color}${message}${colors.reset}`);
}
function createInterface() {
return readline.createInterface({
input: process.stdin,
output: process.stdout
});
}
async function askQuestion(question) {
const rl = createInterface();
return new Promise((resolve) => {
rl.question(question, (answer) => {
rl.close();
resolve(answer.trim());
});
});
}
async function checkExistingNpmrc() {
const npmrcPath = path.join(process.cwd(), '.npmrc');
if (fs.existsSync(npmrcPath)) {
log('\nš .npmrc file already exists', colors.yellow);
const content = fs.readFileSync(npmrcPath, 'utf-8');
const hasToken = content.includes('_password=') && !content.includes('YOUR_TOKEN_HERE');
const hasValidToken = hasToken && !content.includes('cnZxbW91a3NwcWEyZ3d0YmlmdTczNW9kYnBucGJ2ZnRreWxseGpvaXF4bmoyZGFqYmhtYQ==');
if (hasValidToken) {
log('ā
.npmrc already configured with custom token', colors.green);
return true;
} else if (hasToken) {
log('ā ļø .npmrc contains old/expired token', colors.yellow);
const answer = await askQuestion('Do you want to update it? (y/n): ');
return answer.toLowerCase() !== 'y';
} else {
log('ā ļø .npmrc exists but no token configured', colors.yellow);
}
}
return false;
}
function createNpmrcFromTemplate(token) {
const templatePath = path.join(process.cwd(), '.npmrc.template');
const npmrcPath = path.join(process.cwd(), '.npmrc');
if (!fs.existsSync(templatePath)) {
log('ā .npmrc.template not found', colors.red);
log('Please make sure you are in the correct directory', colors.yellow);
return false;
}
try {
let content = fs.readFileSync(templatePath, 'utf-8');
content = content.replace(/YOUR_TOKEN_HERE/g, token);
fs.writeFileSync(npmrcPath, content);
log('ā
.npmrc created successfully', colors.green);
return true;
} catch (error) {
log(`ā Error creating .npmrc: ${error.message}`, colors.red);
return false;
}
}
async function validateNpmrcToken() {
const npmrcPath = path.join(process.cwd(), '.npmrc');
if (!fs.existsSync(npmrcPath)) {
log('ā .npmrc file not found', colors.red);
return false;
}
try {
const content = fs.readFileSync(npmrcPath, 'utf-8');
// Check if token is configured
if (content.includes('YOUR_TOKEN_HERE')) {
log('ā .npmrc token not configured (still contains YOUR_TOKEN_HERE)', colors.red);
return false;
}
// Check for old hardcoded template tokens (but allow valid user tokens)
// Previous validation was too restrictive and blocked legitimate tokens
// Check if token exists
const hasToken = content.includes('_password=') && content.match(/_password=([^\s\n]+)/);
if (hasToken) {
log('ā
.npmrc token is configured', colors.green);
// Try to test the token by checking registry access
log('š Testing registry access...', colors.cyan);
try {
const { execSync } = await import('child_process');
// Test npm registry access
execSync('npm ping --registry http://devops.ccn/CCN%20Platform%20Collection/_packaging/CCN.Platform/npm/registry/', {
stdio: 'pipe'
});
log('ā
Registry access successful', colors.green);
return true;
} catch (error) {
log('ā ļø Registry access failed - token might be expired', colors.yellow);
log('Please check your token validity', colors.yellow);
return false;
}
} else {
log('ā No token found in .npmrc', colors.red);
return false;
}
} catch (error) {
log(`ā Error validating .npmrc: ${error.message}`, colors.red);
return false;
}
}
function addToGitignore() {
const gitignorePath = path.join(process.cwd(), '.gitignore');
const npmrcEntry = '.npmrc\n';
if (fs.existsSync(gitignorePath)) {
const gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8');
if (!gitignoreContent.includes('.npmrc')) {
fs.appendFileSync(gitignorePath, `\n# NPM Configuration with sensitive tokens\n${npmrcEntry}`);
log('ā
Added .npmrc to .gitignore', colors.green);
}
} else {
fs.writeFileSync(gitignorePath, `# NPM Configuration with sensitive tokens\n${npmrcEntry}`);
log('ā
Created .gitignore with .npmrc entry', colors.green);
}
}
function showInstructions() {
log('\n' + '='.repeat(60), colors.cyan);
log('š HOW TO GET YOUR CCN PLATFORM TOKEN', colors.bold + colors.cyan);
log('='.repeat(60), colors.cyan);
log('\n1. Go to CCN DevOps Portal:', colors.yellow);
log(' http://devops.ccn/', colors.blue);
log('\n2. Navigate to your project:', colors.yellow);
log(' ā CCN Platform Collection ā _packaging ā CCN.Platform', colors.blue);
log('\n3. Click "Connect to Feed" or "Generate Token"', colors.yellow);
log('\n4. Select "npm" and copy the _password value', colors.yellow);
log(' Example: cnZxbW91a3NwcWEyZ3d0YmlmdTczNW9kYnBucGJ2ZnRreWxseGpvaXF4bmoyZGFqYmhtYQ==', colors.blue);
log('\n5. Paste the token when prompted below', colors.yellow);
log('\n' + '='.repeat(60), colors.cyan);
}
async function main() {
log('\nš CCN Platform .npmrc Setup', colors.bold + colors.magenta);
log('This tool helps you configure .npmrc for CCN registry access\n', colors.cyan);
const command = process.argv[2];
if (command === 'validate' || command === 'check') {
log('š Validating .npmrc configuration...', colors.cyan);
const isValid = await validateNpmrcToken();
process.exit(isValid ? 0 : 1);
}
if (command === 'help' || command === '--help' || command === '-h') {
showInstructions();
log('\nš Usage:', colors.yellow);
log(' node scripts/setup-npmrc.js # Interactive setup', colors.blue);
log(' node scripts/setup-npmrc.js validate # Validate existing .npmrc', colors.blue);
log(' node scripts/setup-npmrc.js help # Show this help', colors.blue);
return;
}
// Check if already configured
if (await checkExistingNpmrc()) {
return;
}
showInstructions();
const token = await askQuestion('\nš Enter your CCN Platform token (_password value): ');
if (!token || token.length < 20) {
log('ā Invalid token provided', colors.red);
log('Token should be a long base64 string', colors.yellow);
process.exit(1);
}
// Validate token format (should be base64 encoded and reasonable length)
if (token.length < 40) {
log('ā ļø Token appears too short to be valid', colors.yellow);
log('Please verify your token from CCN DevOps Portal', colors.yellow);
process.exit(1);
}
if (createNpmrcFromTemplate(token)) {
addToGitignore();
log('\nā
Setup completed successfully!', colors.bold + colors.green);
log('\nš Next steps:', colors.yellow);
log(' 1. Run: npm install', colors.blue);
log(' 2. Your .npmrc is now configured for CCN registry', colors.blue);
log(' 3. The .npmrc file is added to .gitignore for security', colors.blue);
log('\nš Security Notes:', colors.yellow);
log(' ⢠Never commit .npmrc to version control', colors.red);
log(' ⢠Update your token before expiration', colors.red);
log(' ⢠Run "npm run validate-npmrc" to check token validity', colors.blue);
}
}
// Handle Ctrl+C gracefully
process.on('SIGINT', () => {
log('\n\nš Setup cancelled', colors.yellow);
process.exit(0);
});
main().catch(error => {
log(`\nā Setup failed: ${error.message}`, colors.red);
process.exit(1);
});