ACME HTTP-01 Standalone Challenge Handler
This package provides a lightweight, in-memory HTTP-01 challenge handler for ACME (Automated Certificate Management Environment) clients in Node.js, primarily designed for use with Let's Encrypt. Compatible with ACME.js and Greenlock.js, it specifically addresses the `http-01` challenge type required for domain validation. Currently at version 3.0.5, it emphasizes simplicity and embeddability, featuring zero external dependencies and a minimal codebase (under 150 lines). Its key differentiators include the ability to operate standalone without a dedicated web server and its entirely in-memory operation, making it suitable for quick setups or testing environments. The package is built with Node.js v6 compatibility in mind, offering broad support, though primarily exports CommonJS modules.
Common errors
-
require is not defined in ES module scope
cause Attempting to use `require()` in a JavaScript file that Node.js treats as an ES module (e.g., due to `"type": "module"` in `package.json` or a `.mjs` extension).fixChange the file to a CommonJS module (e.g., rename to `.js` and remove `"type": "module"`), or use dynamic `import()`: `const { create } = await import('acme-http-01-standalone');`. -
http01.set is not a function
cause The `create` method was not called, or the module was imported incorrectly, leading to `http01` not being the challenge handler instance but rather the module's export object.fixEnsure you call `create({})` on the imported module: `const { create } = require('acme-http-01-standalone'); const http01 = create({});`. -
TypeError: Cannot read properties of undefined (reading 'create')
cause The `acme-http-01-standalone` package could not be found or loaded correctly, often due to a missing `node_modules` entry or incorrect path.fixVerify that `acme-http-01-standalone` is listed in your `package.json` and run `npm install` or `yarn install` to ensure it's properly installed.
Warnings
- gotcha This package is explicitly designed for 'in-memory' storage of ACME challenge data. This means any challenge data set will be lost if the Node.js process restarts. It is not suitable for persistent storage or load-balanced environments without an external mechanism to manage state.
- gotcha The package primarily uses CommonJS `require()` exports. While Node.js can often interop between CommonJS and ESM, direct `import { create } from 'acme-http-01-standalone'` might not work as expected in pure ESM projects or require specific Node.js loader configurations.
- gotcha The package states 'node v6 compatible VanillaJS'. While this ensures broad compatibility, it means it doesn't leverage newer JavaScript features or Node.js APIs introduced in later versions, which might affect performance or developer experience in modern environments.
Install
-
npm install acme-http-01-standalone -
yarn add acme-http-01-standalone -
pnpm add acme-http-01-standalone
Imports
- create
import { create } from 'acme-http-01-standalone';const { create } = require('acme-http-01-standalone'); - http01 instance
const http01 = require('acme-http-01-standalone');const http01 = require('acme-http-01-standalone').create({}); - Type definitions
Unfortunately, no official type definitions are currently published for this package.
Quickstart
const Greenlock = require('greenlock-express');
const { create } = require('acme-http-01-standalone');
const http01 = create({});
// Minimal Greenlock setup with the custom http-01 challenge handler
const greenlock = Greenlock.create({
packageRoot: require('path').join(__dirname, '..'),
configDir: './greenlock.d/',
maintainerEmail: 'webmaster@example.com',
cluster: false, // Set to true for production with multiple processes
challenges: {
'http-01': http01
},
// For testing, typically you'd also configure a storage solution
// storage: require('greenlock-pm').create({
// configDir: './greenlock.d/'
// })
});
// Example of setting an ACME challenge (usually done by Greenlock/ACME.js internally)
http01.set({
identifier: { value: 'example.com' },
token: 'someRandomTokenString',
keyAuthorization: 'someRandomTokenString.keyAuthorizationHash'
})
.then(() => {
console.log('ACME challenge data saved to in-memory store.');
// In a real scenario, an ACME client would now attempt to fetch this
// data via HTTP on port 80.
})
.catch(err => {
console.error('Failed to set ACME challenge data:', err);
});