114 lines
3.6 KiB
JavaScript
114 lines
3.6 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 || "");
|
|
}
|