|
|
@@ -0,0 +1,109 @@ |
|
|
var LE = require('letsencrypt'); |
|
|
var pem = require('pem'); |
|
|
var RSVP = require('rsvp'); |
|
|
var fs = require('fs'); |
|
|
var path = require('path'); |
|
|
var mkdirp = require('mkdirp'); |
|
|
|
|
|
var domains, herokuAppName, duplicate; |
|
|
if (process.env.YAPP_ENV === 'qa') { |
|
|
domains = ['heroku.yappqa.us', 'my.yappqa.us', 'api.yappqa.us', 'support.yappqa.us' ]; |
|
|
herokuAppName = 'qa-yapp-cedar'; |
|
|
duplicate = true; // create new cert even if they are less than 1 week old |
|
|
} else if (process.env.YAPP_ENV === 'prod') { |
|
|
domains = ['heroku.yapp.us', 'my.yapp.us', 'api.yapp.us', 'support.yapp.us']; |
|
|
herokuAppName = 'yapp-cedar'; |
|
|
duplicate = false; |
|
|
} else { |
|
|
throw new Error('Must provide valid YAPP_ENV (qa or prod)'); |
|
|
} |
|
|
|
|
|
var redisUrlExtraction = new RSVP.Promise(function(resolve, reject){ |
|
|
var exec = require('child_process').exec; |
|
|
exec('heroku config:get REDISTOGO_URL --app ' + herokuAppName, function (error, stdout, stderr) { |
|
|
var redisUrl = stdout.replace(/\n/, '').replace(/\/\/redistogo:/, '//:'); |
|
|
if (error) { |
|
|
reject(error); |
|
|
} else { |
|
|
resolve(redisUrl); |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
var createPrivateKey = RSVP.denodeify(pem.createPrivateKey); |
|
|
|
|
|
var privateKeyGeneration = createPrivateKey(2048).then(function(privateKey) { |
|
|
var pemPath = require('homedir')() + '/letsencrypt/etc/live/' + domains[0] + '/privkey.pem'; |
|
|
mkdirp.sync(path.dirname(pemPath)); |
|
|
fs.writeFileSync(pemPath, privateKey.key); |
|
|
}).catch(function(reason){ |
|
|
console.log(reason); |
|
|
throw reason; |
|
|
}); |
|
|
|
|
|
privateKeyGeneration.then(function(){ |
|
|
var config = { |
|
|
server: LE.productionServerUrl, |
|
|
manual: true, |
|
|
configDir: require('homedir')() + '/letsencrypt/etc', |
|
|
privkeyPath: ':config/live/:hostname/privkey.pem', |
|
|
fullchainPath: ':config/live/:hostname/fullchain.pem', |
|
|
certPath: ':config/live/:hostname/cert.pem', |
|
|
chainPath: ':config/live/:hostname/chain.pem', |
|
|
debug: true |
|
|
}; |
|
|
|
|
|
var handlers = { |
|
|
setChallenge: function (opts, hostname, key, val, cb) { |
|
|
// called during the ACME server handshake, before validation |
|
|
redisUrlExtraction.then(function(redisUrl){ |
|
|
var redis = require("redis"); |
|
|
var redisClient = redis.createClient(redisUrl); |
|
|
redisClient.set("letsencrypt:" + key, val, function(err){ |
|
|
// console.log("set redis key letsencrypt:" + key + " = " + val); |
|
|
if (err) { |
|
|
console.log(err); |
|
|
throw err; |
|
|
} |
|
|
cb(); |
|
|
}); |
|
|
}).catch(function(reason){ |
|
|
console.log(reason); |
|
|
throw reason; |
|
|
}); |
|
|
}, |
|
|
removeChallenge: function (opts, hostname, key, cb) {} // called after validation on both success and failure |
|
|
}; |
|
|
|
|
|
var le = LE.create(config, handlers); |
|
|
|
|
|
le.register({ // either renews or registers |
|
|
domains: domains, |
|
|
email: '[email protected]', |
|
|
agreeTos: true, |
|
|
duplicate: true |
|
|
}, function (err, results) { |
|
|
if (err) { |
|
|
console.error('[Error]: node-letsencrypt'); |
|
|
console.error(err.stack || err); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (!results || ('object' !== typeof results)) { |
|
|
console.error("Error: An unknown error occurred. My best guess is that we got an error that we're not used to from the ACME server and accidentally interpretted it as a success... or forgot to expose the error."); |
|
|
console.error(results); |
|
|
err = new Error("Here's a stack trace, in case it helps:"); |
|
|
console.error(err.stack); |
|
|
return; |
|
|
} |
|
|
|
|
|
// if (handlers.closeServers) { |
|
|
// handlers.closeServers(); |
|
|
// } |
|
|
|
|
|
console.log('\nCertificate files downloaded! Please run:'); |
|
|
console.log("heroku certs:update " + results.fullchainPath + ' ' + results.privkeyPath + ' --app ' + herokuAppName); |
|
|
|
|
|
process.exit(0); |
|
|
}); |
|
|
}); |