UNPKG

@rnv/engine-core

Version:
225 lines 13.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var path_1 = tslib_1.__importDefault(require("path")); var tar_1 = tslib_1.__importDefault(require("tar")); var util_1 = require("util"); var core_1 = require("@rnv/core"); var fs_1 = require("fs"); var common_1 = require("./common"); var getContext_1 = require("../../getContext"); var taskOptions_1 = require("../../taskOptions"); var iocane = require('iocane'); var readdirAsync = (0, util_1.promisify)(core_1.fsReaddir); var generateRandomKey = function (length) { return Array(length) .fill('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%^&*') .map(function (x) { return x[Math.floor(Math.random() * x.length)]; }) .join(''); }; var initializeCryptoDirectory = function (sourceFolder) { return tslib_1.__awaiter(void 0, void 0, void 0, function () { var ctx, targetFile, options, option, configDir_1, appConfigsDirs; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: ctx = (0, getContext_1.getContext)(); targetFile = 'renative.private.json'; (0, core_1.mkdirSync)(sourceFolder); if (!ctx.paths.project.configPrivateExists) return [3 /*break*/, 2]; options = [ 'Move renative.private.json into encrypted folder (Recommended)', 'Copy renative.private.json into encrypted folder', 'Skip', ]; return [4 /*yield*/, (0, core_1.inquirerPrompt)({ name: 'option', type: 'list', choices: options, message: "Found existing private config in your project ".concat((0, core_1.chalk)().grey(ctx.paths.project.configPrivate), ". What to do next?"), })]; case 1: option = (_a.sent()).option; if (option === options[0]) { (0, core_1.copyFileSync)(ctx.paths.project.configPrivate, path_1.default.join(sourceFolder, targetFile)); (0, core_1.removeFilesSync)([ctx.paths.project.configPrivate]); } else if (option === options[1]) { (0, core_1.copyFileSync)(ctx.paths.project.configPrivate, path_1.default.join(sourceFolder, targetFile)); } _a.label = 2; case 2: if (!(0, core_1.fsExistsSync)(ctx.paths.project.appConfigsDir)) return [3 /*break*/, 4]; configDir_1 = path_1.default.join(sourceFolder, 'appConfigs'); (0, core_1.mkdirSync)(configDir_1); return [4 /*yield*/, readdirAsync(ctx.paths.project.appConfigsDir)]; case 3: appConfigsDirs = _a.sent(); appConfigsDirs.forEach(function (item) { return tslib_1.__awaiter(void 0, void 0, void 0, function () { var appConfigDir, itemPath, stat, existingFiles; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: if (item == targetFile) { (0, core_1.copyFileSync)(path_1.default.join(ctx.paths.project.appConfigsDir, item), path_1.default.join(configDir_1, targetFile)); } appConfigDir = path_1.default.join(configDir_1, item); itemPath = path_1.default.join(ctx.paths.project.appConfigsDir, item); stat = (0, fs_1.statSync)(itemPath); if (!(stat && stat.isDirectory())) return [3 /*break*/, 2]; return [4 /*yield*/, readdirAsync(itemPath)]; case 1: existingFiles = _a.sent(); existingFiles.map(function (file) { if (file === targetFile) { (0, core_1.mkdirSync)(appConfigDir); (0, core_1.mkdirSync)(path_1.default.join(appConfigDir, 'certs')); (0, core_1.copyFileSync)(path_1.default.join(ctx.paths.project.appConfigsDir, item, targetFile), path_1.default.join(appConfigDir, targetFile)); } }); _a.label = 2; case 2: return [2 /*return*/]; } }); }); }); _a.label = 4; case 4: return [2 /*return*/]; } }); }); }; var _checkAndConfigureCrypto = function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () { var ctx, source, cnf, envVar, location_1, sourceFolder, key, keyGenerated, confirm_1; var _a; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: ctx = (0, getContext_1.getContext)(); source = "./".concat((_a = ctx.files.project.config) === null || _a === void 0 ? void 0 : _a.projectName); cnf = ctx.files.project.config_original; if (!cnf) return [2 /*return*/]; envVar = (0, common_1.getEnvVar)(); if (!envVar) return [2 /*return*/]; if (!(ctx.files.project.config && !ctx.files.project.config.crypto)) return [3 /*break*/, 2]; return [4 /*yield*/, (0, core_1.inquirerPrompt)({ type: 'input', name: 'location', message: 'Where would you like your secrets to be residing? (path relative to renative project root, without leading or trailing slash. Ex. `myPrivateConfig/encrypt`)', default: 'secrets', })]; case 1: location_1 = (_b.sent()).location; cnf.crypto = { path: "./".concat(location_1, "/privateConfigs.enc"), }; ctx.files.project.config.crypto = cnf.crypto; (0, core_1.writeFileSync)(ctx.paths.project.config, cnf); _b.label = 2; case 2: sourceFolder = path_1.default.join(ctx.paths.workspace.dir, source); if (!!(0, core_1.fsExistsSync)(sourceFolder)) return [3 /*break*/, 5]; (0, core_1.logInfo)("It seems you are running encrypt for the first time. Directory ".concat((0, core_1.chalk)().bold.white(sourceFolder), " does not exist yet.\nRNV will create it for you, make sure you add whatever you want encrypted in it and then run the command again")); return [4 /*yield*/, initializeCryptoDirectory(sourceFolder)]; case 3: _b.sent(); // writeFileSync(path.join(sourceFolder), ctx.files.project.config); return [4 /*yield*/, (0, core_1.inquirerPrompt)({ type: 'confirm', message: 'Once ready, Continue?', })]; case 4: // writeFileSync(path.join(sourceFolder), ctx.files.project.config); _b.sent(); _b.label = 5; case 5: key = ctx.program.opts().key || ctx.process.env[envVar]; keyGenerated = false; if (!!key) return [3 /*break*/, 7]; return [4 /*yield*/, (0, core_1.inquirerPrompt)({ type: 'confirm', message: "You haven't passed a key with --key or set an env variable named ".concat((0, core_1.chalk)().yellow(envVar), " for the encryption key. Would you like to generate one?"), })]; case 6: confirm_1 = (_b.sent()).confirm; if (confirm_1) { key = generateRandomKey(20); keyGenerated = true; } else { return [2 /*return*/, Promise.reject("encrypt: You must pass ".concat((0, core_1.chalk)().bold.white('--key'), " or have env var defined:\n\n").concat((0, common_1.getEnvExportCmd)(envVar, 'REPLACE_WITH_ENV_VARIABLE'), "\n\nMake sure you take into account special characters that might need to be escaped\n\n"))]; } if (keyGenerated) { (0, core_1.logSuccess)("The files were encrypted with key ".concat((0, core_1.chalk)().red(key), ". Make sure you keep it safe! Pass it with --key on decryption or set it as following env variable:\n\n").concat((0, common_1.getEnvExportCmd)(envVar, key), " \n\nMake sure you take into account special characters that might need to be escaped\n\n")); ctx.process.env[envVar] = key; } _b.label = 7; case 7: return [2 /*return*/]; } }); }); }; exports.default = (0, core_1.createTask)({ description: 'Encrypts secure files from `~/<wokspace>/<project>/..` to project', dependsOn: [core_1.RnvTaskName.configureSoft], fn: function (_a) { var ctx = _a.ctx; return tslib_1.__awaiter(void 0, void 0, void 0, function () { var projectName, source, destRaw, tsWorkspacePath, envVar, key, dest, destTemp, timestamp, destFolder, data; var _b, _c, _d; return tslib_1.__generator(this, function (_e) { switch (_e.label) { case 0: projectName = (_b = ctx.files.project.config) === null || _b === void 0 ? void 0 : _b.projectName; if (!projectName) { return [2 /*return*/, Promise.reject("projectName is missing. Make sure you're in a ReNative project or integration and have projectName defined.")]; } source = "./".concat(projectName); return [4 /*yield*/, _checkAndConfigureCrypto()]; case 1: _e.sent(); destRaw = (_d = (_c = ctx.files.project.config) === null || _c === void 0 ? void 0 : _c.crypto) === null || _d === void 0 ? void 0 : _d.path; tsWorkspacePath = path_1.default.join(ctx.paths.workspace.dir, projectName, 'timestamp'); envVar = (0, common_1.getEnvVar)(); if (!envVar) return [2 /*return*/]; key = ctx.program.opts().key || ctx.process.env[envVar]; if (!destRaw) return [3 /*break*/, 4]; dest = "".concat((0, core_1.getRealPath)(destRaw, 'crypto.path')); destTemp = "".concat(path_1.default.join(ctx.paths.workspace.dir, projectName.replace('/', '-')), ".tgz"); timestamp = new Date().getTime(); destFolder = dest.slice(0, dest.lastIndexOf('/')); !(0, core_1.fsExistsSync)(destFolder) && (0, core_1.mkdirSync)(destFolder); return [4 /*yield*/, tar_1.default.c({ gzip: true, file: destTemp, cwd: ctx.paths.workspace.dir, }, [source])]; case 2: _e.sent(); return [4 /*yield*/, iocane.createSession().use('cbc').encrypt((0, core_1.fsReadFileSync)(destTemp), key)]; case 3: data = _e.sent(); (0, core_1.fsWriteFileSync)(dest, data); // await executeAsync( // c, // `${_getOpenSllPath( // c // )} enc -aes-256-cbc -md md5 -salt -in ${destTemp} -out ${dest} -k ${key}`, // { privateParams: [key] } // ); (0, core_1.removeFilesSync)([destTemp]); (0, core_1.fsWriteFileSync)("".concat(dest, ".timestamp"), "".concat(timestamp)); (0, core_1.fsWriteFileSync)("".concat(tsWorkspacePath), "".concat(timestamp)); (0, core_1.logSuccess)("Files successfully encrypted into ".concat(dest)); return [3 /*break*/, 5]; case 4: (0, core_1.logWarning)("You don't have {{ crypto.path }} specificed in ".concat((0, core_1.chalk)().bold.white(ctx.paths.appConfigBase))); _e.label = 5; case 5: return [2 /*return*/]; } }); }); }, options: [taskOptions_1.TaskOptions.key], task: core_1.RnvTaskName.cryptoEncrypt, }); //# sourceMappingURL=taskCryptoEncrypt.js.map