geocrop-platform./apps/nextgen/server/scripts/refactor-jwt-secret.js

88 lines
2.9 KiB
JavaScript

#!/usr/bin/env node
/**
* One-shot refactor: replace every hardcoded `JWT_SECRET = process.env...
* || 'africa-alert-secret-key-2024'` with `const { jwtSecret: JWT_SECRET }
* = require('../config')` (or relative path appropriate to the file).
*
* Also rewrites inline `process.env.JWT_SECRET || 'africa-alert...'`
* patterns inside `jwt.verify(...)` calls to use the config module.
*
* Idempotent: if the pattern is already converted, the file is left alone.
*
* Usage: `node server/scripts/refactor-jwt-secret.js [path1 path2 ...]`
* If no paths given, operates on every server/src/*.js file.
*/
const fs = require('fs');
const path = require('path');
const HARD_CODED_LINE =
/const\s+JWT_SECRET\s*=\s*process\.env\.JWT_SECRET\s*\|\|\s*'africa-alert-secret-key-2024'\s*;/g;
const INLINE_PATTERN =
/process\.env\.JWT_SECRET\s*\|\|\s*'africa-alert-secret-key-2024'/g;
function relativeConfigRequire(filePath) {
// file is in server/src/controllers/X.js or server/src/services/X.js
// config is in server/src/config/index.js
// require path is ../config from controllers/services, ./config from index.js
if (filePath.endsWith('index.js') && /[\\/]server[\\/]src[\\/]index\.js$/.test(filePath)) {
return './config';
}
return '../config';
}
function* walk(dir) {
if (!fs.existsSync(dir)) return;
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
if (entry.name === 'node_modules' || entry.name === 'config' || entry.name.startsWith('.')) continue;
const full = path.join(dir, entry.name);
if (entry.isDirectory()) {
yield* walk(full);
} else if (full.endsWith('.js')) {
yield full;
}
}
}
function refactorFile(filePath) {
const original = fs.readFileSync(filePath, 'utf8');
let content = original;
const requirePath = relativeConfigRequire(filePath);
// Pattern 1: top-level const JWT_SECRET = ... || 'africa-alert-...'
content = content.replace(HARD_CODED_LINE, (match) => {
// Preserve any leading whitespace
const indent = (match.match(/^(\s*)/) || ['', ''])[1];
return `${indent}const { jwtSecret: JWT_SECRET } = require('${requirePath}');`;
});
// Pattern 2: inline `process.env.JWT_SECRET || 'africa-alert-...'` inside jwt.verify(...)
content = content.replace(INLINE_PATTERN, `require('${requirePath}').jwtSecret`);
if (content !== original) {
fs.writeFileSync(filePath, content);
return true;
}
return false;
}
const args = process.argv.slice(2);
const targets = args.length > 0
? args
: [path.join(__dirname, '..', 'src')];
let changed = 0;
let visited = 0;
for (const target of targets) {
for (const file of walk(target)) {
visited++;
if (refactorFile(file)) {
changed++;
console.log(' refactored: ' + path.relative(process.cwd(), file));
}
}
}
console.log(`\nDone. Visited ${visited} files, refactored ${changed}.`);
console.log('Next: grep for "africa-alert-secret-key-2024" — should be 0 hits.');