# [greenlock-store-test](https://git.rootprojects.org/root/greenlock-store-test.js.git) | A [Root](https://rootprojects.org) Project The test harness you should use when writing a certificate and keypair storage strategy for [Greenlock](https://git.coolaj86.com/coolaj86/greenlock-express.js) v2.7+ (and v3). All implementations MUST pass these tests, which is a very easy thing to do (just 3 getter/setter pairs to implement). The tests account for single-domain certificates (`example.com`) as well as multiple domain certs (SAN / AltName), wildcards (`*.example.com`), and valid private / localhost certificates. As someone creating a challenge strategy that's not something you have to take special consideration for - just pass the tests. ## Install ```bash npm install --save-dev greenlock-store-test@3.x ``` ## Usage ```js var tester = require('greenlock-store-test'); //var store = require('greenlock-store-memory').create({}); //var store = require('greenlock-store-fs').create({}); var store = require('./YOUR-STORAGE-STRATEGY').create({}); // All of these tests can pass locally, standalone without any ACME integration. tester.test(store).then(function () { console.info("PASS"); }); ``` ## Reference Implementations These are plugins that use the v2.7+ (v3) API, and pass this test harness, which you should use as a model for any plugins that you create. * [`greenlock-store-memory`](https://git.rootprojects.org/root/greenlock-store-memory.js) * [`greenlock-store-fs`](https://git.rootprojects.org/root/greenlock-store-fs.js) ## Example See `example.js` (it works). ## Looking for the Easy Button? [Contact Root](mailto:support@rootprojects.org) If you're looking for fast and inexpensive plugin development, we can deliver greater value in less time than most outsouring options. We can also work with your in-house team to give a quick, inexpensive 10x boost to internal development success. We also offer commercial licenses for LTS (Long-Term Support) versions of Greenlock. ## Overview The most generic implementation, with no special considerations or custom logic, ends up looking like this: ```js tester.test({ // ACME user account accounts: { setKeypair: function (opts) { // { account: { id: '...' } // you may or may not receive 'id' // , email: 'jon.doe@example.com' // , keypair: { privateKeyPem: '...', privateKeyJwk: {...} } // } var id = opts.account.id || opts.email; return DB.Keypairs.save(id, JSON.stringify(opts.keypair)); } , checkKeypair: function (opts) { // you receive the same options as setKeypair() above var id = opts.account.id || opts.email; return DB.Keypairs.get(id).then(function (k) { return JSON.parse(k); }); } } // Site Keys & Certificates , certificates: { // Site Keys (privkey.pem a.k.a. example.com.key) setKeypair: function (opts) { // { certificate: { kid: '...', id: '...' } // you may or may not receive 'kid' or 'id' // , subject: 'foo.example.com' // , keypair: { privateKeyPem: '...', privateKeyJwk: {...} } // } var id = opts.certificate.kid || opts.certificate.id || opts.subject; return DB.Keypairs.save(id, JSON.stringify(opts.keypair)); } , checkKeypair: function (opts) { // you receive the same options as setKeypair() above var id = opts.certificate.kid || opts.certificate.id || opts.subject; return DB.Keypairs.get(id).then(function (x) { return JSON.parse(x); }); } // Certificates (fullchain.pem a.k.a. cert.pem a.k.a. example.com.crt) , set: function (opts) { // { certificate: { id: '...' } // you may or may not receive 'id' // , subject: 'foo.example.com' // , pems: { cert: '...', chain: '...', ... } // } var id = opts.certificate.id || opts.subject; return DB.Certificates.save(id, JSON.stringify(opts.keypair)); } , set: function (opts) { // { certificate: { id: '...' } // you may or may not receive 'id' // , subject: 'foo.example.com' // , pems: { cert: '...', chain: '...', ... } // } var id = opts.certificate.id || opts.subject; return DB.Certificates.save(id, JSON.stringify(opts.keypair)); } } }).then(function () { console.info("PASS"); }); ``` Note: The `DB.x.y()` is where you do your magic up to connect to a database or API or whatever and keep stuff safe.