From b80ab1ae54148da3cce9b2bcfd41e092766c3d43 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Tue, 30 Jul 2019 23:58:48 -0600 Subject: [PATCH] v3.0.0: HTTP Authentication for Let's Encrypt --- README.md | 25 +++++-------------- example.env | 1 - lib/index.js | 61 +++++++++++------------------------------------ package-lock.json | 7 +----- package.json | 14 +++++------ test.js | 20 +--------------- 6 files changed, 28 insertions(+), 100 deletions(-) diff --git a/README.md b/README.md index 4b4bc70..568ae68 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# [acme-http-01-webroot.js](https://git.rootprojects.org/root/acme-http-01-webroot.js) | a [Root](https://rootprojects.org/) project +# [acme-http-01-standalone.js](https://git.rootprojects.org/root/acme-http-01-standalone.js) | a [Root](https://rootprojects.org/) project -Webroot Authentication + Let's Encrypt for Node.js - ACME http-01 challenges w/ ACME.js and Greenlock.js +In-memory HTTP Authentication for Let's Encrypt for Node.js - ACME http-01 challenges w/ ACME.js and Greenlock.js Handles ACME http-01 challenges. Compatible with ACME.js and Greenlock.js. Passes acme-http-01-test. @@ -8,10 +8,7 @@ Handles ACME http-01 challenges. Compatible with ACME.js and Greenlock.js. Passe - Compatible - Let’s Encrypt v2.1 / ACME draft 18 (2019) - - Works with your web root - - Apache - - Nginx - - Lighttpd + - Works standalone, without a separate web server - ACME.js, Greenlock.js, and others - Quality - node v6 compatible VanillaJS @@ -21,7 +18,7 @@ Handles ACME http-01 challenges. Compatible with ACME.js and Greenlock.js. Passe # Install ```js -npm install --save acme-http-01-webroot +npm install --save acme-http-01-standalone ``` # Usage @@ -29,17 +26,7 @@ npm install --save acme-http-01-webroot First you create an instance with your credentials: ```js -var http01 = require('acme-http-01-webroot').create({ - webroot: '~/.local/tmp/acme-challenge' // default -}); -``` - -Template example: - -```js -var http01 = require('acme-http-01-webroot').create({ - webroot: '/srv/www/{domain}/.well-known/acme-challenge' -}); +var http01 = require('acme-http-01-standalone').create({}); ``` Then you can use it with any compatible ACME library, such as Greenlock.js or ACME.js. @@ -108,7 +95,7 @@ See AUTHORS for contact info. # Legal -[acme-http-01-webroot.js](https://git.coolaj86.com/coolaj86/acme-http-01-webroot.js) | MPL-2.0 | [Terms of Use](https://therootcompany.com/legal/#terms) | [Privacy Policy](https://therootcompany.com/legal/#privacy) +[acme-http-01-standalone.js](https://git.coolaj86.com/coolaj86/acme-http-01-standalone.js) | MPL-2.0 | [Terms of Use](https://therootcompany.com/legal/#terms) | [Privacy Policy](https://therootcompany.com/legal/#privacy) Copyright 2019 AJ ONeal Copyright 2019 The Root Group LLC diff --git a/example.env b/example.env index 2b2242b..79b10df 100644 --- a/example.env +++ b/example.env @@ -1,2 +1 @@ RECORD=example.co.uk -WEBROOT=/tmp/acme-challenge diff --git a/lib/index.js b/lib/index.js index 3f2fe38..5495c0a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,32 +1,13 @@ 'use strict'; //var request; -var promisify = require('util').promisify; -var os = require('os'); -var fs = require('fs'); -var writeFile = promisify(fs.writeFile); -var readFile = promisify(fs.readFile); -var unlink = promisify(fs.unlink); -var mkdirp = promisify(require('@root/mkdirp')); -var path = require('path'); -var defaults = { - webroot: path.join(require('os').tmpdir(), 'acme-challenge') -}; +var defaults = {}; module.exports.create = function(config) { - var webroot = config.webroot || config.webrootPath || defaults.webroot; - - function tpl(str, ch) { - return str - .replace(/\s*{+\s*domain\s*}+\s*/gi, ch.identifier.value) - .replace(/^~/, os.homedir()); - } + var memdb = config.cache || {}; return { - // exposed to make testable - _tpl: tpl, - init: function(opts) { //request = opts.request; return null; @@ -36,47 +17,33 @@ module.exports.create = function(config) { // console.log('Add Key Auth URL', data); var ch = data.challenge; - var pathname = tpl(webroot, ch); + var key = ch.identifier.value + '#' + ch.token; + memdb[key] = ch.keyAuthorization; - return mkdirp(pathname) - .then(function() { - return writeFile( - path.join(pathname, ch.token), - ch.keyAuthorization - ); - }) - .then(function() { - return null; - }); + return null; }, get: function(data) { // console.log('List Key Auth URL', data); var ch = data.challenge; - var pathname = tpl(webroot, ch); + var key = ch.identifier.value + '#' + ch.token; - return readFile(path.join(pathname, ch.token), 'utf8') - .then(function(keyAuth) { - return { keyAuthorization: keyAuth }; - }) - .catch(function(err) { - if ('ENOENT' !== err.code) { - throw err; - } - return null; - }); + if (memdb[key]) { + return { keyAuthorization: memdb[key] }; + } + + return null; }, remove: function(data) { // console.log('Remove Key Auth URL', data); var ch = data.challenge; - var pathname = tpl(webroot, ch); + var key = ch.identifier.value + '#' + ch.token; - return unlink(path.join(pathname, ch.token)).then(function() { - return null; - }); + delete memdb[key]; + return null; } }; }; diff --git a/package-lock.json b/package-lock.json index 0ce2ca1..74fa378 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,9 @@ { - "name": "acme-http-01-webroot", + "name": "acme-http-01-standalone", "version": "3.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { - "@root/mkdirp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@root/mkdirp/-/mkdirp-1.0.0.tgz", - "integrity": "sha512-hxGAYUx5029VggfG+U9naAhQkoMSXtOeXtbql97m3Hi6/sQSRL/4khKZPyOF6w11glyCOU38WCNLu9nUcSjOfA==" - }, "@root/request": { "version": "1.3.11", "resolved": "https://registry.npmjs.org/@root/request/-/request-1.3.11.tgz", diff --git a/package.json b/package.json index 1e9e742..94055c5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "acme-http-01-webroot", + "name": "acme-http-01-standalone", "version": "3.0.0", - "description": "Webroot Authentication + Let's Encrypt for Node.js - ACME http-01 challenges w/ ACME.js and Greenlock.js", + "description": "HTTP Authentication (In-Memory) for Let's Encrypt for Node.js - ACME http-01 challenges w/ ACME.js and Greenlock.js", "main": "index.js", "files": [ "lib", @@ -12,11 +12,11 @@ }, "repository": { "type": "git", - "url": "https://git.coolaj86.com/coolaj86/acme-http-01-webroot.js.git" + "url": "https://git.coolaj86.com/coolaj86/acme-http-01-standalone.js.git" }, "keywords": [ - "webroot", - "storage", + "standalone", + "memory", "http-01", "letsencrypt", "acme", @@ -31,7 +31,5 @@ "acme-challenge-test": "^3.3.2", "dotenv": "^8.0.0" }, - "dependencies": { - "@root/mkdirp": "^1.0.0" - } + "dependencies": {} } diff --git a/test.js b/test.js index b3f1291..ee314dc 100755 --- a/test.js +++ b/test.js @@ -7,11 +7,7 @@ require('dotenv').config(); // Usage: node ./test.js example.com username xxxxxxxxx var record = process.argv[2] || process.env.RECORD; -var challenger = require('./index.js').create({ - webroot: - '/tmp/acme-tests/{domain}/.well-known/acme-challenges/' || - process.env.WEBROOT -}); +var challenger = require('./index.js').create({}); // The dry-run tests can pass on, literally, 'example.com' // but the integration tests require that you have control over the domain @@ -24,17 +20,3 @@ tester console.error(e.message); console.error(e.stack); }); - -var ch = { identifier: { value: 'foo.example.co.uk' } }; -//var ch = { domain: 'foo.example.co.uk' }; -var homeish = challenger._tpl('~/.local/tmp/acme-challenge', ch); -console.log(homeish); -if ('/' !== homeish[0] || /~/.test(homeish)) { - throw new Error('Not the expected value for home tmp: ' + homeish); -} - -var srvish = challenger._tpl('/srv/{domain}/.well-known/acme-challenge', ch); -console.log(srvish); -if ('/' !== srvish[0] || /~/.test(srvish)) { - throw new Error('Not the expected value for srv template: ' + srvish); -}