mediacentral-sign
Version:
Signing tool for mediacentral cloud-ux apps
211 lines (183 loc) • 8.13 kB
JavaScript
let readFilesRecursive = (() => {
var _ref = _asyncToGenerator(function* (file) {
if (yield fs.lstatPromise(file).then(function (s) {
return s.isFile();
})) {
return [file];
}
return fs.readdirPromise(file).then(function (files) {
return Promise.all(files.map(function (currentFile) {
return path.join(file, currentFile);
}).map(readFilesRecursive)).then(function (sub_dir_files) {
return sub_dir_files.reduce(function (p, v) {
return [...p, ...v];
}, []);
});
});
});
return function readFilesRecursive(_x) {
return _ref.apply(this, arguments);
};
})();
let writeJsonFile = (() => {
var _ref2 = _asyncToGenerator(function* (file, object) {
logger.info('----- Creating manifest.json -----');
logger.trace('writing object ', object, ' to file ', file);
return fs.writeFilePromise(file, JSON.stringify(object, null, 2));
});
return function writeJsonFile(_x2, _x3) {
return _ref2.apply(this, arguments);
};
})();
let getHashes = (() => {
var _ref3 = _asyncToGenerator(function* (keyFile, password, dir, files) {
logger.info('----- Creating hashes for files -----');
const hashes = {};
const privateKey = fs.readFileSync(keyFile, 'utf-8');
yield Promise.all(files.map(function (f) {
return (
// use of fs.readFile from ./fs does not work for some reson in app creator tool
// If someone knows why it wotks in tests and does not work as extension in vscode tell me!
Promise.resolve(fs1.readFileSync(path.join(dir, f))).then(function (data) {
const signer = crypto.createSign('sha512');
signer.update(data);
const sign = signer.sign({ key: privateKey, passphrase: password }, 'base64');
hashes[f !== '' ? f : path.basename(dir)] = sign;
})
);
}));
return hashes;
});
return function getHashes(_x4, _x5, _x6, _x7) {
return _ref3.apply(this, arguments);
};
})();
let optionsValidation = (() => {
var _ref4 = _asyncToGenerator(function* (options) {
logger.trace('options passed to validation: ', (yield stripObjectFromPassword(options)));
logger.info('----- Passed options are valid -----');
if (!options.hasOwnProperty('key')) {
throw new Error('A key file not set!');
}
if (!options.hasOwnProperty('file')) {
throw new Error('File not set!');
}
if (!options.hasOwnProperty('manifest')) {
throw new Error('A manifest file not set!');
}
if (typeof options.key !== 'string') {
throw new Error('Path to a key file must be a string.');
}
if (typeof options.manifest !== 'string') {
throw new Error('Path to a manifest file must be a string.');
}
if (typeof options.file !== 'string' && !Array.isArray(options.file)) {
throw new Error('File to sign must be a string or array of strings.');
}
if (options.password && typeof options.password !== 'string') {
throw new Error('Password must be a string.');
}
if (options.id && typeof options.id !== 'string') {
throw new Error('developers ID must be a string.');
}
if (!(yield fs.existsPromise(options.key))) {
throw new Error(`Path to a key file (${options.key}) is invalid.`);
}
if (Array.isArray(options.file)) {
yield Promise.all(options.file.map(function (f) {
return fs.existsPromise(f).then(function (exists) {
if (!exists) {
throw new Error(`Path to a directory or file to sign (${f}) is invalid.`);
}
});
}));
} else if (!(yield fs.existsPromise(options.file))) {
throw new Error(`Path to a directory or file to sign (${options.file}) is invalid.`);
}
if ((yield fs.existsPromise(options.manifest)) && !(yield fs.lstatPromise(options.manifest).then(function (s) {
return s.isFile();
}))) {
throw new Error(`A manifest file (${options.manifest}) musn't be a directory.`);
}
if (!(yield fs.lstatPromise(options.key).then(function (s) {
return s.isFile();
}))) {
throw new Error(`A key file (${options.key}) musn't be a directory.`);
}
});
return function optionsValidation(_x8) {
return _ref4.apply(this, arguments);
};
})();
let readFiles = (() => {
var _ref5 = _asyncToGenerator(function* (file) {
logger.info('----- Reading files to sign -----');
return (Array.isArray(file) ? Promise.all(file.map(function (fi) {
return readFilesRecursive(fi);
})).then(function (files) {
return files.reduce(function (p, v) {
return [...p, ...v];
}, []);
}) : readFilesRecursive(file)).then(function (files) {
return files.map(function (f) {
return path.relative(file, f);
});
});
});
return function readFiles(_x9) {
return _ref5.apply(this, arguments);
};
})();
let verifyManifest = (() => {
var _ref6 = _asyncToGenerator(function* (manifestPath, pubKeyPath) {
logger.trace(`verifyManifest with path: `, manifestPath, ` and key: `, pubKeyPath);
const publicKey = fs.readFileSync(pubKeyPath, 'utf-8');
const filesName = require(manifestPath).files;
const filesPath = path.dirname(manifestPath);
const verifyResult = {};
Object.entries(filesName).forEach(function ([key, value]) {
const verification = crypto.createVerify('SHA512');
const readFile = fs.readFileSync(path.join(filesPath, key), 'utf8');
verification.update(readFile);
const verifiedFile = verification.verify(publicKey, value, 'base64');
verifyResult[key] = verifiedFile;
});
logger.trace(`Verified result of manifest: `, verifyResult);
return verifyResult;
});
return function verifyManifest(_x10, _x11) {
return _ref6.apply(this, arguments);
};
})();
let stripObjectFromPassword = (() => {
var _ref7 = _asyncToGenerator(function* (optionsObject) {
const OBJECT_SCHEMA = joi.object().keys({
key: joi.string().allow(""),
file: joi.string().allow(""),
id: joi.string().allow(""),
files: joi.string().allow("")
});
const options = {
stripUnknown: true
};
return joi.validate(optionsObject, OBJECT_SCHEMA, options).value;
});
return function stripObjectFromPassword(_x12) {
return _ref7.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const path = require('path');
const crypto = require('crypto');
const fs = require('./fs');
const fs1 = require('fs');
const logger = require.main.require('log4js').getLogger(`avid-sign ${__filename}`);
const joi = require('joi');
module.exports = {
optionsValidation,
readFiles,
writeJsonFile,
getHashes,
verifyManifest,
readFilesRecursive
};