gl-store-s3.js/index.js

254 lines
10 KiB
JavaScript

////////////////////////////
// File names for support //
////////////////////////////
const fileNames = {
privkey: {
pem: 'privkey.pem'
, jwk: 'privkey.jwk'
}
, cert: 'cert.pem'
, chain: 'chain.pem'
, fullchain: 'fullchain.pem'
, bundle: 'bundle.pem'
}
///////////////////////////
// Setup the environment //
///////////////////////////
var path = require('path');
var Promise = require('bluebird')
const AWS = require('aws-sdk');
AWS.config.setPromisesDependency(Promise);
const defaultOptions = {
accessKeyId: null
, secretAccessKey: null
, bucketName: null
, bucketRegion: null
, accountsDir: 'accounts/'
, configDir: 'acme/'
}
const s3 = new AWS.S3({ apiVersion: '2006-03-01' });
module.exports.create = (createOptions) => {
const options = Object.assign({}, defaultOptions, createOptions);
if (!options.debug) {
console = console || {};
console.log = () => { };
console.error = () => { };
}
AWS.config.update({
region: options.bucketRegion
, credentials: new AWS.Credentials({
accessKeyId: options.accessKeyId
, secretAccessKey: options.secretAccessKey
})
});
const handlers = {
certificates: {
check: (opts) => {
var id = opts.certificate && opts.certificate.id || opts.subject;
console.log('certificates.check for', opts.subject);
var privkeyPath = certificatesPath(options, id, fileNames.privkey.pem);
var certPath = certificatesPath(options, id, fileNames.cert);
var chainPath = certificatesPath(options, id, fileNames.chain);
return Promise.all([
s3.getObject({ Key: privkeyPath, Bucket: options.bucketName }).promise().then((data) => {
console.log('Successfully retrieved certificate privkey.pem');
return data.Body.toString();
}).catch((err) => {
console.error('There was an error retrieving your certificate privkey.pem:', err.message);
throw err;
}),
s3.getObject({ Key: certPath, Bucket: options.bucketName }).promise().then((data) => {
console.log('Successfully retrieved certificate cert.pem');
return data.Body.toString();
}).catch((err) => {
console.error('There was an error retrieving your certificate cert.pem:', err.message);
throw err;
}),
s3.getObject({ Key: chainPath, Bucket: options.bucketName }).promise().then((data) => {
console.log('Successfully retrieved certificate chain.pem');
return data.Body.toString();
}).catch((err) => {
console.error('There was an error retrieving your certificate chain.pem:', err.message);
throw err;
})
]).then((values) => {
// console.log('Promise.all(values):', values);
return {
privkey: values[0]
, cert: values[1]
, chain: values[2]
}
}).catch((err) => {
console.error('There was an error checking the ceritifcates:', err.message);
return null;
});
},
checkKeypair: (opts) => {
console.log('certificates.checkKeypair for', opts.subject);
id = opts.certificate.kid || opts.certificate.id || opts.subject;
pemKeyPath = certificatesPath(options, id, fileNames.privkey.pem);
jwkKeyPath = certificatesPath(options, id, fileNames.privkey.jwk);
return s3.getObject({ Key: pemKeyPath, Bucket: options.bucketName }).promise().then((data) => {
console.log('Successfully retrieved certificate PEM keypair.');
return {
privateKeyPem: data.Body.toString()
}
}).catch((err) => {
console.error('There was an error retrieving your certificate PEM keypair:', err.message);
return null
});
},
setKeypair: (opts) => {
id = opts.certificate.kid || opts.certificate.id || opts.subject;
console.log('certificates.setKeypair for', id);
pemKeyPath = certificatesPath(options, id, fileNames.privkey.pem);
jwkKeyPath = certificatesPath(options, id, fileNames.privkey.jwk);
return s3.putObject({ Key: pemKeyPath, Body: opts.keypair.privateKeyPem, Bucket: options.bucketName }).promise().then((data) => {
console.log('Successfully set the PEM privateKey.');
return null;
}).catch((err) => {
console.error('There was an error setting your PEM privateKey:', err.message);
throw err;
});
},
set: (opts) => {
console.log('certificates.set for ', opts.subject);
var pems = {
cert: opts.pems.cert
, chain: opts.pems.chain
, privkey: opts.pems.privkey
}
var certPath = certificatesPath(options, opts.subject, fileNames.cert);
var chainPath = certificatesPath(options, opts.subject, fileNames.chain);
var fullchainPath = certificatesPath(options, opts.subject, fileNames.fullchain);
var bundlePath = certificatesPath(options, opts.subject, fileNames.bundle);
var fullchainPem = [pems.cert, pems.chain].join('\n'); // for Apache, Nginx, etc
var bundlePem = [pems.privkey, pems.cert, pems.chain].join('\n'); // for HAProxy
return Promise.all([
s3.putObject({ Key: certPath, Body: pems.cert, Bucket: options.bucketName }).promise().then((data) => {
console.log('Successfully set', certPath);
}).catch((err) => {
console.error('There was an error setting cert.pem:', err.message);
throw err;
}),
s3.putObject({ Key: chainPath, Body: pems.chain, Bucket: options.bucketName }).promise().then((data) => {
console.log('Successfully set', chainPath);
}).catch((err) => {
console.error('There was an error setting chain.pem:', err.message);
throw err;
}),
s3.putObject({ Key: fullchainPath, Body: fullchainPem, Bucket: options.bucketName }).promise().then((data) => {
console.log('Successfully set', fullchainPath);
}).catch((err) => {
console.error('There was an error setting fullchain.pem:', err.message);
throw err;
}),
s3.putObject({ Key: bundlePath, Body: bundlePem, Bucket: options.bucketName }).promise().then((data) => {
console.log('Successfully set', bundlePath);
}).catch((err) => {
console.error('There was an error setting bundle.pem:', err.message);
throw err;
})
]).then((values) => {
return null;
}).catch((err) => {
console.error('There was an error setting the certificates:', err.message);
throw err;
});
}
},
accounts: {
check: (opts) => {
console.log("accounts.check", opts.account.id);
// console.log(opts);
},
checkKeypair: (opts) => {
var id = opts.account.id || opts.email || 'single-user';
console.log('accounts.checkKeypair for', id);
key = accountsPath(options, id)
return s3.getObject({ Key: key, Bucket: options.bucketName }).promise().then((data) => {
console.log('Successfully retrieved account keypair.');
var keypair = JSON.parse(data.Body.toString());
return {
privateKeyPem: keypair.privateKeyPem // string PEM private key
, privateKeyJwk: keypair.privateKeyJwk // object JWK private key
};
}).catch((err) => {
console.error('There was an error retrieving your account keypair:', err.message);
return null;
});
},
setKeypair: (opts) => {
console.log('accounts.setKeypair for', opts.account);
var id = opts.account.id || opts.email || 'single-user';
key = accountsPath(options, id)
var body = JSON.stringify({
privateKeyPem: opts.keypair.privateKeyPem // string PEM
, privateKeyJwk: opts.keypair.privateKeyJwk // object JWK
});
return s3.putObject({ Key: key, Body: body, Bucket: options.bucketName }).promise().then((data) => {
console.log('Successfully created account keypair.');
return null;
}).catch((err) => {
console.error('There was an error creating account keypair:', err.message);
return null;
});
},
set: (opts) => {
console.log("accounts.set");
}
}
}
return handlers;
}
const certificatesPath = (options, id, fileName) => {
var filePath = path.join(options.configDir, 'live', tameWild(id), fileName);
console.log('filePath:', filePath);
return filePath;
}
const accountsPath = (options, id) => {
var filePath = path.join(options.configDir, options.accountsDir, tameWild(id) + '.json');
console.log('filePath:', filePath);
return filePath;
}
const tameWild = (wild) => {
return wild.replace(/\*/g, '_');
}