@rnv/engine-core
Version:
ReNative Engine Core
225 lines • 13.2 kB
JavaScript
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
;