diff --git a/home/scripts/add-content-to-registry.js b/home/scripts/add-content-to-registry.js index 9a08049..cfde2f3 100644 --- a/home/scripts/add-content-to-registry.js +++ b/home/scripts/add-content-to-registry.js @@ -13,8 +13,7 @@ const forceUpdate = args.includes('--force') || args.includes('-f'); const verbose = args.includes('--verbose') || args.includes('-v'); const dryRun = args.includes('--dry-run') || args.includes('-d'); -// Afficher l'aide -if (showHelp) { +function printHelp() { console.log(` 📚 Script d'ajout de contenu au registry @@ -47,7 +46,6 @@ EXEMPLES: # Combinaison d'options node add-content-to-registry.js --dry-run --verbose `); - process.exit(0); } // Statistiques @@ -85,12 +83,19 @@ function validateJSON(filePath, content) { /** * Convertit une URL GitHub en chemin local */ -function githubUrlToLocalPath(githubUrl) { +function githubUrlToLocalPath(githubUrl, baseTemplatesDir = templatesDir) { if (!githubUrl.startsWith(GITHUB_BASE_URL)) { return null; } const relativePath = githubUrl.replace(GITHUB_BASE_URL, ''); - return path.join(templatesDir, relativePath); + const templatesRoot = path.resolve(baseTemplatesDir); + const localPath = path.resolve(templatesRoot, relativePath); + + if (localPath !== templatesRoot && !localPath.startsWith(templatesRoot + path.sep)) { + return null; + } + + return localPath; } /** @@ -303,50 +308,60 @@ function printSummary() { } } -// ============================================ -// EXECUTION PRINCIPALE -// ============================================ - -console.log('🚀 Script d\'ajout de contenu au registry\n'); -console.log('Options:'); -if (dryRun) console.log(' 🔍 Mode DRY RUN (simulation)'); -if (forceUpdate) console.log(' 🔄 Force la mise Ă  jour mĂȘme si content existe'); -if (verbose) console.log(' 📝 Mode verbeux activĂ©'); -console.log(''); - -// VĂ©rifier que les rĂ©pertoires existent -if (!fs.existsSync(registryDir)) { - console.error(`❌ Erreur: Le rĂ©pertoire ${registryDir} n'existe pas`); - process.exit(1); -} +function main() { + if (showHelp) { + printHelp(); + process.exit(0); + } -if (!fs.existsSync(templatesDir)) { - console.error(`❌ Erreur: Le rĂ©pertoire ${templatesDir} n'existe pas`); - process.exit(1); -} + console.log('🚀 Script d\'ajout de contenu au registry\n'); + console.log('Options:'); + if (dryRun) console.log(' 🔍 Mode DRY RUN (simulation)'); + if (forceUpdate) console.log(' 🔄 Force la mise Ă  jour mĂȘme si content existe'); + if (verbose) console.log(' 📝 Mode verbeux activĂ©'); + console.log(''); + + // VĂ©rifier que les rĂ©pertoires existent + if (!fs.existsSync(registryDir)) { + console.error(`❌ Erreur: Le rĂ©pertoire ${registryDir} n'existe pas`); + process.exit(1); + } -// Lire tous les fichiers JSON -const jsonFiles = fs.readdirSync(registryDir) - .filter(f => f.endsWith('.json')) - .sort(); + if (!fs.existsSync(templatesDir)) { + console.error(`❌ Erreur: Le rĂ©pertoire ${templatesDir} n'existe pas`); + process.exit(1); + } -if (jsonFiles.length === 0) { - console.log('⚠ Aucun fichier JSON trouvĂ© dans le rĂ©pertoire registry'); - process.exit(0); -} + // Lire tous les fichiers JSON + const jsonFiles = fs.readdirSync(registryDir) + .filter(f => f.endsWith('.json')) + .sort(); + + if (jsonFiles.length === 0) { + console.log('⚠ Aucun fichier JSON trouvĂ© dans le rĂ©pertoire registry'); + process.exit(0); + } -console.log(`📂 ${jsonFiles.length} fichier${jsonFiles.length > 1 ? 's' : ''} JSON trouvĂ©${jsonFiles.length > 1 ? 's' : ''}\n`); + console.log(`📂 ${jsonFiles.length} fichier${jsonFiles.length > 1 ? 's' : ''} JSON trouvĂ©${jsonFiles.length > 1 ? 's' : ''}\n`); -// Traiter chaque fichier -jsonFiles.forEach(jsonFile => { - processJSONFile(jsonFile); -}); + // Traiter chaque fichier + jsonFiles.forEach(jsonFile => { + processJSONFile(jsonFile); + }); -// Afficher le rĂ©sumĂ© -printSummary(); + // Afficher le rĂ©sumĂ© + printSummary(); -// Code de sortie -if (stats.jsonFiles.errors > 0 || stats.contentFiles.errors > 0) { - process.exit(1); + // Code de sortie + if (stats.jsonFiles.errors > 0 || stats.contentFiles.errors > 0) { + process.exit(1); + } } +module.exports = { + githubUrlToLocalPath, +}; + +if (require.main === module) { + main(); +} diff --git a/home/scripts/add-content-to-registry.test.js b/home/scripts/add-content-to-registry.test.js new file mode 100644 index 0000000..ff037a8 --- /dev/null +++ b/home/scripts/add-content-to-registry.test.js @@ -0,0 +1,14 @@ +const assert = require("node:assert/strict"); +const { describe, it } = require("node:test"); +const path = require("node:path"); +const { githubUrlToLocalPath } = require("./add-content-to-registry"); + +describe("githubUrlToLocalPath", () => { + it("rejects trusted-prefix paths that escape the templates directory", () => { + const templatesDir = path.join(__dirname, "..", "..", "templates"); + const crafted = + "https://raw.githubusercontent.com/ln-dev7/square-ui/master/templates/../../home/.env"; + + assert.equal(githubUrlToLocalPath(crafted, templatesDir), null); + }); +});