feat(handlers): Add in-memory HTTP-01 challenge handler and rename file-based handler to Http01Webroot
This commit is contained in:
67
ts/handlers/Http01MemoryHandler.ts
Normal file
67
ts/handlers/Http01MemoryHandler.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import type { IChallengeHandler } from './IChallengeHandler.js';
|
||||
|
||||
/**
|
||||
* HTTP-01 ACME challenge handler using in-memory storage.
|
||||
* Stores challenge tokens and key authorizations in memory
|
||||
* and serves them via handleRequest for arbitrary HTTP servers.
|
||||
*/
|
||||
export interface Http01MemoryHandlerChallenge {
|
||||
type: string;
|
||||
token: string;
|
||||
keyAuthorization: string;
|
||||
webPath: string;
|
||||
}
|
||||
|
||||
export class Http01MemoryHandler implements IChallengeHandler<Http01MemoryHandlerChallenge> {
|
||||
private store: Map<string, string> = new Map();
|
||||
|
||||
public getSupportedTypes(): string[] {
|
||||
return ['http-01'];
|
||||
}
|
||||
|
||||
public async prepare(ch: Http01MemoryHandlerChallenge): Promise<void> {
|
||||
this.store.set(ch.token, ch.keyAuthorization);
|
||||
}
|
||||
|
||||
public async verify(_ch: Http01MemoryHandlerChallenge): Promise<void> {
|
||||
// No-op
|
||||
return;
|
||||
}
|
||||
|
||||
public async cleanup(ch: Http01MemoryHandlerChallenge): Promise<void> {
|
||||
this.store.delete(ch.token);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP request handler for serving ACME HTTP-01 challenges.
|
||||
* @param req HTTP request object (should have url property)
|
||||
* @param res HTTP response object
|
||||
* @param next Optional next() callback for Express-style fallthrough
|
||||
*/
|
||||
public handleRequest(req: any, res: any, next?: () => void): void {
|
||||
const url = req.url || '';
|
||||
const prefix = '/.well-known/acme-challenge/';
|
||||
if (!url.startsWith(prefix)) {
|
||||
if (next) {
|
||||
return next();
|
||||
}
|
||||
res.statusCode = 404;
|
||||
return res.end();
|
||||
}
|
||||
const token = url.slice(prefix.length);
|
||||
const keyAuth = this.store.get(token);
|
||||
if (keyAuth !== undefined) {
|
||||
if (typeof res.status === 'function' && typeof res.send === 'function') {
|
||||
return res.status(200).send(keyAuth);
|
||||
}
|
||||
res.statusCode = 200;
|
||||
res.setHeader('content-type', 'text/plain');
|
||||
return res.end(keyAuth);
|
||||
}
|
||||
if (next) {
|
||||
return next();
|
||||
}
|
||||
res.statusCode = 404;
|
||||
return res.end();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user