base-acme-client v30.0.3
Automatic Certificate Management Environment (ACME)
A module for interacting with ACME
servers for automated SSL/TLS certificate issuance and management.
Exports
import * as bac from 'base-acme-client'; // ES6
newDirectory
Fetches the directory information from an ACME
server.
/**
* Fetches the directory information from an ACME server.
* @async
*
* @param {string} mainDirectoryUrl - The URL of the ACME server's directory endpoint
*
* @returns {Promise<Object>} An object containing the directory information or an error
* @property {Object|null} get - The parsed directory JSON or null
*
* @property {null|Object} error - The error response if the request was unsuccessful
*/
export async function newDirectory(mainDirectoryUrl) { /*...*/ }
newNonce
Retrieves a new nonce from the ACME
server.
/**
* Retrieves a new nonce from the ACME server.
* @async
*
* @param {string} [newNonceUrl] - ACME Directory URL to fetch a new nonce.
*
* @returns {Promise<Object>} An object containing the nonce or error details
* @property {string|null} nonce - A new replay nonce for subsequent requests
*
* @property {null|Object} error - The error response if the request was unsuccessful
*/
export async function newNonce(newNonceUrl) { /*...*/ }
createJsonWebKey
Creates a JSON Web Key (JWK) from a public key.
/**
* Creates a JSON Web Key (JWK) from a public key.
* @async
*
* @param {Object} publicKey - The public key to convert to JWK format
*
* @returns {Promise<Object>} An object containing the JWK and its thumbprint
* @property {Object} key - The JSON Web Key representation
* @property {string} print - Base64URL encoded thumbprint of the key
*/
export async function createJsonWebKey(publicKey) { /*...*/ }
createAccount
Creates a new account on the ACME
server.
/**
* Creates a new account on the ACME server.
* @async
*
* @param {string} nonce - The replay nonce from the server
* @param {string} newAccountUrl - The URL for creating a new account
* @param {Object} privateKey - The private key for signing the request
* @param {Object} jsonWebKey - The JSON Web Key representing the account's public key
* @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations
*
* @returns {Promise<Object>} An object containing the account creation result
* @property {Object|null} get - The created account details
* @property {string|null} location - The location URL of the created account
* @property {string|null} nonce - A new replay nonce for subsequent requests
*
* @property {null|Object} error - Error details if account creation fails
*/
export async function createAccount(nonce, newAccountUrl, privateKey, jsonWebKey) { /*...*/ }
createOrder
Creates a new order for certificate issuance on the ACME
server.
/**
* Creates a new order for certificate issuance on the ACME server.
* @async
*
* @param {string} kid - Key Identifier for the account
* @param {string} nonce - The replay nonce from the server
* @param {Object} privateKey - The private key for signing the request
* @param {string[]} identifiers - Domain names to be included in the certificate
* @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations
*
* @returns {Promise<Object>} An object containing the order creation result
* @property {Object|null} get - The created order details
* @property {string|null} location - The location URL of the created order
* @property {string|null} nonce - A new replay nonce for subsequent requests
*
* @property {null|Object} error - Error details if order creation fails
*/
export async function createOrder(kid, nonce, privateKey, newOrderUrl, identifiers) { /*...*/ }
finalizeOrder
Finalizes a certificate order by submitting a Certificate Signing Request (CSR).
/**
* Finalizes a certificate order by submitting a Certificate Signing Request (CSR).
* @async
*
* @param {string} commonName - The primary domain name for the certificate
* @param {string} kid - Key Identifier for the account
* @param {string} nonce - The replay nonce from the server
* @param {Object} privateKey - The private key for signing the request
* @param {Object} publicKeySign - Public key used for signing the CSR
* @param {Object} privateKeySign - Private key used for signing the CSR
* @param {string} finalizeUrl - The URL for finalizing the order
* @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations
* @param {string[]} dnsNames - Additional DNS names to be included in the certificate
*
* @returns {Promise<Object>} An object containing the order finalization result
* @property {Object|null} get - The finalized order details
* @property {string|null} location - The location URL of the finalized order
* @property {string|null} nonce - A new replay nonce for subsequent requests
*
* @property {null|Object} error - Error details if finalization fails
*/
export async function finalizeOrder(commonName, kid, nonce, privateKey, publicKeySign, privateKeySign, finalizeUrl, dnsNames) { /*...*/ }
postAsGet
Performs a POST-as-GET request to retrieve order or authorization status.
/**
* Performs a POST-as-GET request to retrieve order or authorization status.
* @async
*
* @param {string} kid - Key Identifier for the account
* @param {string} nonce - The replay nonce from the server
* @param {Object} privateKey - The private key for signing the request
* @param {string} url - The URL to retrieve status from
* @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations
*
* @returns {Promise<Object>} An object containing the retrieved information
* @property {Object|null} get - The retrieved resource details
* @property {string|null} location - The location URL of the resource
* @property {string|null} nonce - A new replay nonce for subsequent requests
*
* @property {null|Object} error - Error details if retrieval fails
*/
export async function postAsGet(kid, nonce, privateKey, url) { /*...*/ }
postAsGetChal
Performs a POST-as-GET request for challenges
/**
* Performs a POST-as-GET request for challenges
* @async
*
* @param {string} kid - Key Identifier for the account
* @param {string} nonce - The replay nonce from the server
* @param {Object} privateKey - The private key for signing the request
* @param {string} url - The URL to retrieve challenge details from
* @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations
*
* @returns {Promise<Object>} An object containing the challenge details
* @property {Object|null} get - The retrieved challenge details
* @property {string|null} location - The location URL of the challenge
* @property {string|null} nonce - A new replay nonce for subsequent requests
*
* @property {null|Object} error - Error details if retrieval fails
*/
export async function postAsGetChal(kid, nonce, privateKey, url) { /*...*/ }
signPayloadJson
Signs a JSON payload for ACME
server requests.
/**
* Signs a JSON payload for ACME server requests.
* @async
*
* @param {Object} payload - The payload to be signed
* @param {Object} protectedHeader - The protected header containing metadata
* @param {Object} privateKey - The private key used for signing
*
* @returns {Promise<string>} A JSON Web Signature (JWS) string
*/
export async function signPayloadJson(payload, protectedHeader, privateKey) { /*...*/ }
signPayload
Signs a payload for ACME
server requests.
/**
* Signs a payload for ACME server requests.
* @async
*
* @param {string|Object} payload - The payload to be signed
* @param {Object} protectedHeader - The protected header containing metadata
* @param {Object} privateKey - The private key used for signing
*
* @returns {Promise<string>} A JSON Web Signature (JWS) string
*/
export async function signPayload(payload, protectedHeader, privateKey) { /*...*/ }
formatPublicKey
Formats a PEM-encoded public key to a key object.
/**
* Formats a PEM-encoded public key to a key object.
*
* @param {string} pem - The PEM-encoded public key
*
* @returns {Object} A formatted public key object
*/
export function formatPublicKey(pem) { /*...*/ }
formatPrivateKey
Formats a PEM-encoded private key to a key object.
/**
* Formats a PEM-encoded private key to a key object.
*
* @param {string} pem - The PEM-encoded private key
*
* @returns {Object} A formatted private key object
*/
export function formatPrivateKey(pem) { /*...*/ }
base64urlEncode
Encodes input to a base64url-encoded string.
/**
* Encodes input to a base64url-encoded string.
*
* @param {string|Uint8Array} input - The input to encode
*
* @returns {string} A base64url-encoded string
*/
export function base64urlEncode(input) { /*...*/ }
hexToBytes
Converts a hexadecimal string to a Uint8Array of bytes.
/**
* Converts a hexadecimal string to a Uint8Array of bytes.
*
* @param {string} hex - The hexadecimal string to convert. It should contain an even number of characters.
*
* @returns {Uint8Array} A Uint8Array containing the byte values represented by the hexadecimal string.
* @throws {Error} Throws an error if the input string has an odd length or contains invalid hexadecimal characters.
*/
export function hexToBytes(hex) { /*...*/ }
getNextNonce
Retrieves the next nonce for ACME protocol requests.
/**
* Retrieves the next nonce for ACME protocol requests.
*
* If a replay nonce is provided in the headers, it will return that nonce.
* Otherwise, it will request a new nonce from the ACME directory.
*
* @async
*
* @param {Headers} headers - The headers object containing the replay nonce.
* @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations
*
* @returns {Promise<string|null>} A promise that resolves to the next nonce as a string,
* or null if no nonce is available.
*/
export async function getNextNonce(headers, acmeDirectory) { /*...*/ }
fetchRequest
Sends a signed request to the ACME
server.
/**
* Sends a signed request to the ACME server.
* @async
*
* @param {string} method - The HTTP method to use (e.g., 'GET', 'POST')
* @param {string} url - The URL to send the request to
* @param {string} signedData - The signed payload to send
*
* @returns {Promise<Response>} The response from the server
*/
export async function fetchRequest(method, url, signedData) { /*...*/ }
fetchSuggestedWindow
Fetches the suggested renewal window information for a certificate from the specified URL.
/**
* Fetches the suggested renewal window information for a certificate from the specified URL.
* @async
*
* @param {string} renewalInfoUrl - The base URL for fetching renewal information.
* @param {string} aki- The Authority Key Identifier in hexadecimal format.
* @param {string} serial - The serial number in hexadecimal format.
*
* @returns {Promise<Object>} A promise that resolves to the parsed JSON of the suggested window
* @property {Object|null} get - The retrieved suggested window
*
* @property {null|Object} error - Error details if retrieval fails
*
* @throws {Error} Throws an error if the fetch operation fails.
*/
export async function fetchSuggestedWindow(renewalInfoUrl, aki, serial) { /*...*/ }
fetchAndRetryUntilOk
Fetch a resource with multiple retry attempts and progressive backoff.
/**
* Fetch a resource with multiple retry attempts and progressive backoff.
* @async
*
* @param {string|Request} fetchInput - The URL or Request object to fetch
* @param {Object} init - optional fetch init object
* @param {number} [attempts=6] - Maximum number of fetch attempts
* @param {boolean} silent - true to suppress console output on failure attempt
*
* @returns {Promise<Response|undefined>} The response or undefined if all attempts fail
*
* @description
* This function attempts to fetch a resource with the following characteristics:
* - Starts with one fetch attempt
* - Increments attempts progressively
* - Implements an increasing delay between failed attempts (650ms * attempt number)
* - Logs any caught exceptions
* - Returns immediately on a successful (ok) response
* - Returns the last response or undefined if all attempts are exhausted
*
* @example
* const response = await fetchAndRetyUntilOk('https://api.example.com/data');
* if (response && response.ok) {
* const data = await response.json();
* // Process successful response
* }
*/
export async function fetchAndRetryUntilOk(fetchInput, init, attempts = 6, silent = false) { /*...*/ }
fetchAndRetryProtectedUntilOk
Fetch a protected resource with multiple retry attempts and progressive backoff.
/**
* Fetch a protected resource with multiple retry attempts and progressive backoff.
* @async
*
* @param {Object} payload - The payload to be sent with the request
* @param {Object} protectedHeader - The protected header containing metadata for the request
* @param {Object} privateKey - The private key for signing the request
* @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations
* @param {number} [attempts=6] - Maximum number of fetch attempts (default: 6)
* @param {boolean} silent - true to suppress console output on failure attempt
*
* @returns {Promise<Response|undefined>} The response or undefined if all attempts fail
*
* @description
* This function attempts to fetch a protected resource with the following characteristics:
* - Starts with one fetch attempt
* - Increments attempts progressively
* - Implements an increasing delay between failed attempts (650ms * attempt number)
* - Logs any caught exceptions
* - Returns immediately on a successful (ok) response
* - Returns the last response or undefined if all attempts are exhausted
*
* @example
* const response = await fetchAndRetryProtectedUntilOk(
* payload,
* protectedHeader,
* privateKey,
* acmeDirectory
* );
* if (response && response.ok) {
* const data = await response.json();
* // Process successful response
* }
*/
export async function fetchAndRetryProtectedUntilOk(payload, protectedHeader, privateKey, acmeDirectory, attempts = 3, silent = false) { /*...*/ }
Errors/Exceptions
Errors and Exceptions will be returned in an object
// Exceptions
{
error: {
type: 'bac:exception:methodName',
detail: Error: SyntaxError: Unexpected end of input
at file:///base-acme-client.js:666:11
at ModuleJob.run (node:internal/modules/esm/module_job:271:25)
at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:547:26)
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:116:5),
status: 777777
}
}
// Error from the Base ACME Client
{
error: {
type: 'bac:failed:methodName',
detail: 'Could not complete methodName after multiple attempts',
status: 777777
}
}
// Error from the ACME Server
{
error: {
type: 'urn:ietf:params:acme:error:orderNotReady',
detail: `Order's status ("valid") is not acceptable for finalization`,
status: 403
}
}
Full Working Examples
This module is used by Lets Encrypt ACME Client
and Server SSL
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago