114 lines
3.2 KiB
JavaScript
114 lines
3.2 KiB
JavaScript
|
'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 || '');
|
||
|
}
|