Replaced the creation of one new folder in tmpDir for each manifest to the creation in tmpDir of one manifest with unique generated uuid

Added some comments;
Renamed some parameters
This commit is contained in:
Alexander Cerutti
2018-05-07 22:04:51 +02:00
parent d3b4a17e84
commit 1d0ed48084

View File

@@ -1,11 +1,11 @@
const express = require("express"); const os = require("os");
const fs = require("fs");
const path = require("path");
const crypto = require("crypto"); const crypto = require("crypto");
const { spawn } = require("child_process"); const { spawn } = require("child_process");
const os = require("os");
const path = require("path");
const archiver = require("archiver"); const archiver = require("archiver");
const express = require("express");
const async = require("async"); const async = require("async");
const fs = require("fs");
const _configuration = Object.freeze(require("./config.json")); const _configuration = Object.freeze(require("./config.json"));
@@ -23,9 +23,7 @@ const Certificates = _configuration.certificates;
*/ */
function removeDotFiles(from) { function removeDotFiles(from) {
return from.filter(e => { return from.filter(e => e.charAt(0) !== ".");
return e.charAt(0) !== "."
});
} }
function capitalizeFirst(str) { function capitalizeFirst(str) {
@@ -51,6 +49,13 @@ function checkSignatureRequirements() {
return Promise.all([checkCertificate, checkKey]); return Promise.all([checkCertificate, checkKey]);
} }
/**
Generates a unique UUID
From Github Gist: https://gist.github.com/jed/982883
*/
function UUIDGen(a){return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,UUIDGen)}
/** /**
Generates the cryptografic signature for the manifest file. Generates the cryptografic signature for the manifest file.
Spawns Openssl process since Node.js has no support for PKCSs. Spawns Openssl process since Node.js has no support for PKCSs.
@@ -60,7 +65,7 @@ function checkSignatureRequirements() {
@returns {Object} Promise @returns {Object} Promise
*/ */
function generateManifestSignature(manifestPath) { function generateManifestSignature(manifestUUID) {
return new Promise(function(done, rejected) { return new Promise(function(done, rejected) {
checkSignatureRequirements() checkSignatureRequirements()
.then(function() { .then(function() {
@@ -74,7 +79,7 @@ function generateManifestSignature(manifestPath) {
"-certfile", path.resolve(Certificates.dir, Certificates.files["wwdr_pem"]), "-certfile", path.resolve(Certificates.dir, Certificates.files["wwdr_pem"]),
"-signer", path.resolve(Certificates.dir, Certificates.files["certificate"]), "-signer", path.resolve(Certificates.dir, Certificates.files["certificate"]),
"-inkey", path.resolve(Certificates.dir, Certificates.files["key"]), "-inkey", path.resolve(Certificates.dir, Certificates.files["key"]),
"-in", path.resolve(`${manifestPath}/manifest.json`), "-in", path.resolve(`${os.tmpdir()}/manifest-${manifestUUID}.json`),
// "-out", path.resolve("passCreator", "event.pass", "./signature"), // "-out", path.resolve("passCreator", "event.pass", "./signature"),
"-outform", "DER", "-outform", "DER",
"-passin", `pass:${Certificates.credentials["dev_pem_key"]}` "-passin", `pass:${Certificates.credentials["dev_pem_key"]}`
@@ -103,18 +108,28 @@ function generateManifestSignature(manifestPath) {
}); });
} }
function generateManifest(fromObject, tempFolderPath) { /**
Generates a Buffer of JSON file (manifest)
@function generateManifest
@params {Object} fromObject - Manifest content
@params {String} manifestUUID
@return {Promise} - Promise with the manifest buffer
@see https://apple.co/2IhJr0Q (PassKit Package Structure)
@see https://apple.co/2K2aY3v (Passes Are Cryptographically Signed and Compressed)
*/
function generateManifest(fromObject, manifestUUID) {
return new Promise(function(done, failed) { return new Promise(function(done, failed) {
if (!fromObject || typeof fromObject !== "object" && typeof fromObject !== "string") { if (!fromObject || typeof fromObject !== "object" && typeof fromObject !== "string") {
return failed("generateManifest: Argument 0 is required and must be of an object or a string (source object)"); return failed("generateManifest: Argument 0 is required and must be of an object or a string (source object)");
} }
if (!tempFolderPath || typeof tempFolderPath !== "string") { if (!manifestUUID || typeof manifestUUID !== "string") {
return failed("generateManifest: Argument 1 is required and must be a string (temporary folder path for manifest)"); return failed("generateManifest: Argument 1 is required and must be a string (unique uuid).");
} }
const source = typeof fromObject === "object" ? JSON.stringify(fromObject) : fromObject; const source = typeof fromObject === "object" ? JSON.stringify(fromObject) : fromObject;
let manifestWS = fs.createWriteStream(`${tempFolderPath}/manifest.json`); let manifestWS = fs.createWriteStream(`${os.tmpdir()}/manifest-${manifestUUID}.json`);
manifestWS.write(source); manifestWS.write(source);
manifestWS.end(); manifestWS.end();
@@ -164,18 +179,6 @@ instance.get("/gen/:type/", function (req, res) {
return; return;
} }
/*
* Creating a temporary directory to keep the manifest.json of each pass.
* This is done to pass the file as openssl parameter.
* It would be better to pass openssl a buffer but sadly it seems not possible.
* Feel free to contribute if you think there's a better way to achieve this.
*/
fs.mkdtemp(path.join(os.tmpdir(), "passkitWebServer-"), function(err, tempFolder) {
if (err) {
throw err;
}
// Manifest dictionary // Manifest dictionary
let manifestRaw = {}; let manifestRaw = {};
let archive = archiver("zip"); let archive = archiver("zip");
@@ -209,12 +212,14 @@ instance.get("/gen/:type/", function (req, res) {
throw new Error(`Unable to compile manifest. ${error}`); throw new Error(`Unable to compile manifest. ${error}`);
} }
generateManifest(manifestRaw, tempFolder) let uuid = UUIDGen();
generateManifest(manifestRaw, uuid)
.then(function(manifestBuffer) { .then(function(manifestBuffer) {
archive.append(manifestBuffer, { name: "manifest.json" }); archive.append(manifestBuffer, { name: "manifest.json" });
generateManifestSignature(tempFolder) generateManifestSignature(uuid)
.then(function(signatureBuffer) { .then(function(signatureBuffer) {
if (!fs.existsSync("output")) { if (!fs.existsSync("output")) {
@@ -247,4 +252,3 @@ instance.get("/gen/:type/", function (req, res) {
}); });
}); });
}); });
});