'use strict'; var accounts = module.exports; var store = accounts; var U = require('./utils.js'); var fs = require('fs'); var path = require('path'); var PromiseA = require('./promise.js'); var readFileAsync = PromiseA.promisify(fs.readFile); var writeFileAsync = PromiseA.promisify(fs.writeFile); var mkdirpAsync = PromiseA.promisify(require('@root/mkdirp')); // Implement if you need the ACME account metadata elsewhere in the chain of events //store.accounts.check = function (opts) { // console.log('accounts.check for', opts.account, opts.email); // return PromiseA.resolve(null); //}; // Accounts.checkKeypair // // Use account.id, or email, if id hasn't been set, to find an account keypair. // Return an object with string privateKeyPem and/or object privateKeyJwk (or null, not undefined) accounts.checkKeypair = function(opts) { var id = (opts.account && opts.account.id) || (opts.subscriberEmail || opts.email) || 'single-user'; //console.log('accounts.checkKeypair for', id); var pathname = path.join( accountsDir(store, opts), sanitizeFilename(id) + '.json' ); return readFileAsync(U._tameWild(pathname, opts.subject), 'utf8') .then(function(blob) { // keypair can treated as an opaque object and just passed along, // but just to show you what it is... var keypair = JSON.parse(blob); return keypair; /* { privateKeyPem: keypair.privateKeyPem, // string PEM private key privateKeyJwk: keypair.privateKeyJwk, // object JWK private key private: keypair.private, public: keypair.public }; */ }) .catch(function(err) { if ('ENOENT' === err.code) { return null; } throw err; }); }; // Accounts.setKeypair({ account, email, keypair, ... }): // // Use account.id (or email if no id is present) to save an account keypair // Return null (not undefined) on success, or throw on error accounts.setKeypair = function(opts) { //console.log('accounts.setKeypair for', opts.account, opts.email, opts.keypair); var id = opts.account.id || opts.email || 'single-user'; // you can just treat the keypair as opaque and save and retrieve it as JSON var keyblob = JSON.stringify(opts.keypair); /* var keyblob = JSON.stringify({ privateKeyPem: opts.keypair.privateKeyPem, // string PEM privateKeyJwk: opts.keypair.privateKeyJwk, // object JWK private: opts.keypair.private }); */ // Ignore. // Just implementation specific details here. return mkdirpAsync(accountsDir(store, opts)) .then(function() { var pathname = path.join( accountsDir(store, opts), sanitizeFilename(id) + '.json' ); return writeFileAsync( U._tameWild(pathname, opts.subject), keyblob, 'utf8' ); }) .then(function() { // This is your job: return null, not undefined return null; }); }; // Implement if you need the ACME account metadata elsewhere in the chain of events //accounts.set = function (opts) { // console.log('account.set:', opts.account, opts.email, opts.receipt); // return PromiseA.resolve(null); //}; function sanitizeFilename(id) { return id.replace(/(\.\.)|\\|\//g, '_').replace(/[^!-~]/g, '_'); } function accountsDir(store, opts) { var dir = U._tpl( store, opts, opts.accountsDir || store.options.accountsDir ); return U._tameWild(dir, opts.subject || ''); }