From d5e7e11256ef177124cc121c873004dfca309397 Mon Sep 17 00:00:00 2001 From: Philipp Kunz Date: Sun, 27 Apr 2025 14:39:59 +0000 Subject: [PATCH] feat(readme): Update documentation with detailed built-in challenge handlers and custom handler examples --- changelog.md | 7 ++++ readme.md | 72 ++++++++++++++++++++++++++++++++++++++-- ts/00_commitinfo_data.ts | 2 +- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index 02f59dc..fa05416 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2025-04-27 - 6.1.0 - feat(readme) +Update documentation with detailed built-in challenge handlers and custom handler examples + +- Expanded readme to include sections on Dns01Handler and Http01Handler usage +- Added examples for creating and registering custom ACME challenge handlers +- Improved clarity of ACME certificate management instructions using SmartAcme + ## 2025-04-27 - 6.0.1 - fix(readme) Remove extraneous code fence markers from license section in readme diff --git a/readme.md b/readme.md index 9d1a99b..ca56cba 100644 --- a/readme.md +++ b/readme.md @@ -138,8 +138,76 @@ async function main() { await smartAcmeInstance.stop(); } -main().catch(console.error); -``` + main().catch(console.error); + ``` + + ## Built-in Challenge Handlers + + This module includes two out-of-the-box ACME challenge handlers: + + - **Dns01Handler** + - Uses a Cloudflare account (from `@apiclient.xyz/cloudflare`) and Smartdns client to set and remove DNS TXT records, then wait for propagation. + - Import path: + ```typescript + import { Dns01Handler } from '@push.rocks/smartacme/ts/handlers/Dns01Handler.js'; + ``` + - Example: + ```typescript + import * as cloudflare from '@apiclient.xyz/cloudflare'; + const cfAccount = new cloudflare.CloudflareAccount('CF_TOKEN'); + const dnsHandler = new Dns01Handler(cfAccount); + ``` + + - **Http01Handler** + - Writes ACME HTTP-01 challenge files under a file-system webroot (`/.well-known/acme-challenge/`), and removes them on cleanup. + - Import path: + ```typescript + import { Http01Handler } from '@push.rocks/smartacme/ts/handlers/Http01Handler.js'; + ``` + - Example: + ```typescript + const httpHandler = new Http01Handler({ webroot: '/var/www/html' }); + ``` + + Both handlers implement the `IChallengeHandler` interface and can be combined in the `challengeHandlers` array. + + ## Creating Custom Handlers + + To support additional challenge types or custom validation flows, implement the `IChallengeHandler` interface: + + ```typescript + import type { IChallengeHandler } from '@push.rocks/smartacme/ts/handlers/IChallengeHandler.js'; + + // Define your custom challenge payload type + interface MyChallenge { type: string; /* ... */ } + + class MyCustomHandler implements IChallengeHandler { + getSupportedTypes(): string[] { + return ['my-01']; + } + + // Prepare the challenge (set DNS records, start servers, etc.) + async prepare(ch: MyChallenge): Promise { + // preparation logic + } + + // Optional verify step after prepare + async verify?(ch: MyChallenge): Promise { + // verification logic + } + + // Cleanup after challenge (remove records, stop servers) + async cleanup(ch: MyChallenge): Promise { + // cleanup logic + } + } + + // Then register your handler: + const customInstance = new SmartAcme({ + /* other options */, + challengeHandlers: [ new MyCustomHandler() ], + challengePriority: ['my-01'], + }); In this example, `Qenv` is used to manage environment variables, and `cloudflare` library is used to handle DNS challenges required by Let's Encrypt ACME protocol. The `setChallenge` and `removeChallenge` methods are essential for automating the DNS challenge process, which is a key part of domain validation. diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 68ee350..14cd8ec 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartacme', - version: '6.0.1', + version: '6.1.0', description: 'A TypeScript-based ACME client for LetsEncrypt certificate management with a focus on simplicity and power.' }