UNPKG

@jtff/slots-protector

Version:

protect all human slots with individual password and give a folder with all the passwords by coalitions

128 lines (115 loc) 7.26 kB
"use strict"; const fs = require("fs"); const path = require("path"); const blake2 = require("blake2"); const base64url = require('base64url'); const slugify = require('slugify'); const templatelib = require('@jtff/miztemplate-lib'); const mizlib = new templatelib.Mizlib(); if (process.env.NODE_ENV === "production") { console.debug = () => { }; } function generatePassword(length) { let saltKey = new Array(11).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36)[Math.random()<.5?"toString":"toUpperCase"]();}); let clearPassword = new Array(length).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36)[Math.random()<.5?"toString":"toUpperCase"]();}); let hash = blake2.createKeyedHash('blake2b', Buffer.from(saltKey), {digestLength: 32}).update(Buffer.from(clearPassword)).digest(); return { clear: clearPassword, hash: saltKey + ":" + base64url(hash) }; } function generateGroupInfo(groupObject, credentialObject) { return { groupName: groupObject.name, groupId: groupObject.groupId, force: Object.keys(groupObject.units).length, unitIds: Object.values(groupObject.units).map(x => x.unitId), tailNumbers: Object.values(groupObject.units).map(x => x.onboard_num), model: groupObject.units["1"].type, password: credentialObject.clear }; } console.log("slots-protector"); if (process.argv.length <= 2) { console.error("missing file argument !!!"); process.exit(1); } const inputMizPath = process.argv[2]; if (!(fs.existsSync(inputMizPath))) { console.error("file " + process.argv[2] + " not found !!\nExiting."); process.exit(2); } const outputMizPath = "./out/passwd_" + path.basename(inputMizPath); fs.rmSync("./out", {recursive: true, force: true}); fs.mkdirSync("./out/coalitions", {recursive: true}); fs.copyFileSync(inputMizPath,outputMizPath); mizlib.getZipObjectFromMizPath(outputMizPath).then(mizData => { console.debug("miz File loaded"); mizData.files["mission"].async('nodebuffer').then(content => { fs.writeFileSync("./out/mission-orig.lua", content); }); mizlib.getMissionObjectFromZipObject(mizData).then(missionObject => { mizData.remove("mission"); Object.keys(missionObject.coalition).forEach(function(coalitionKey, coalitionIndex, coalitionArray) { console.debug("coalitions : name = " + missionObject.coalition[coalitionKey].name); Object.keys(missionObject.coalition[coalitionKey].country).forEach(function(contryKey, countryIndex, countryArray) { console.debug("country : name = " + missionObject.coalition[coalitionKey].country[contryKey].name); if (Object.hasOwn(missionObject.coalition[coalitionKey].country[contryKey], 'plane')) { fs.mkdirSync("./out/coalitions/" + missionObject.coalition[coalitionKey].name + "/airplanes", {recursive: true}); Object.keys(missionObject.coalition[coalitionKey].country[contryKey].plane.group).forEach(function(groupKey, index, array) { const groupObject = missionObject.coalition[coalitionKey].country[contryKey].plane.group[groupKey]; console.debug("Plane group : name = " + missionObject.coalition[coalitionKey].country[contryKey].plane.group[groupKey].name); const listSkills = Object.values(missionObject.coalition[coalitionKey].country[contryKey].plane.group[groupKey].units).map(x => x.skill).find(element => element === "Client"); if (typeof listSkills !== 'undefined' && listSkills) { if (!(Object.hasOwn(groupObject, 'password'))) { const passwordObject = generatePassword(20); fs.writeFileSync("./out/coalitions/" + missionObject.coalition[coalitionKey].name + "/airplanes/" + slugify(groupObject.name) + "-info.json", JSON.stringify(generateGroupInfo(groupObject, passwordObject), null, " ")); console.debug("group: " + groupObject.name); console.debug("generate Password = " + passwordObject.clear); console.debug("generate hash = " + passwordObject.hash); missionObject.coalition[coalitionKey].country[contryKey].plane.group[groupKey].password=passwordObject.hash; } } else { console.debug("not Human slot"); } }); } if (Object.hasOwn(missionObject.coalition[coalitionKey].country[contryKey], 'helicopter')) { fs.mkdirSync("./out/coalitions/" + missionObject.coalition[coalitionKey].name + "/helicopters", {recursive: true}); Object.keys(missionObject.coalition[coalitionKey].country[contryKey].helicopter.group).forEach(function(groupKey, index, array) { const groupObject = missionObject.coalition[coalitionKey].country[contryKey].helicopter.group[groupKey]; console.debug("helicopter group : name = " + missionObject.coalition[coalitionKey].country[contryKey].helicopter.group[groupKey].name); const listSkills = Object.values(missionObject.coalition[coalitionKey].country[contryKey].helicopter.group[groupKey].units).map(x => x.skill).find(element => element === "Client"); if (typeof listSkills !== 'undefined' && listSkills) { if (!(Object.hasOwn(groupObject, 'password'))) { const passwordObject = generatePassword(20); fs.writeFileSync("./out/coalitions/" + missionObject.coalition[coalitionKey].name + "/helicopters/" + slugify(groupObject.name) + "-info.json", JSON.stringify(generateGroupInfo(groupObject, passwordObject), null, " ")); console.debug("group: " + groupObject.name); console.debug("generate Password = " + passwordObject.clear); console.debug("generate hash = " + passwordObject.hash); missionObject.coalition[coalitionKey].country[contryKey].helicopter.group[groupKey].password=passwordObject.hash; } } else { console.debug("not Human slot"); } }); } }); }); const missionLuaT = "mission = " + mizlib.js2Lua(missionObject); mizData.file("mission", missionLuaT); mizData.generateAsync({ type: 'nodebuffer', streamFiles: true, compression: "DEFLATE", compressionOptions: { level: 9 } }).then(zipData => { fs.writeFileSync(outputMizPath, zipData); mizData.files["mission"].async('nodebuffer').then(content => { fs.writeFileSync("./out/mission-modified.lua", content); }); }); }); })