before refactor
This commit is contained in:
@ -2,6 +2,21 @@ import * as plugins from '../plugins.js';
|
||||
import { IncomingMessage, ServerResponse } from 'http';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
// ACME HTTP-01 challenge handler storing tokens in memory (diskless)
|
||||
class DisklessHttp01Handler {
|
||||
private storage: Map<string, string>;
|
||||
constructor(storage: Map<string, string>) { this.storage = storage; }
|
||||
public getSupportedTypes(): string[] { return ['http-01']; }
|
||||
public async prepare(ch: any): Promise<void> {
|
||||
this.storage.set(ch.token, ch.keyAuthorization);
|
||||
}
|
||||
public async verify(ch: any): Promise<void> {
|
||||
return;
|
||||
}
|
||||
public async cleanup(ch: any): Promise<void> {
|
||||
this.storage.delete(ch.token);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom error classes for better error handling
|
||||
@ -79,6 +94,7 @@ interface IPort80HandlerOptions {
|
||||
autoRenew?: boolean; // Whether to automatically renew certificates
|
||||
certificateStore?: string; // Directory to store certificates
|
||||
skipConfiguredCerts?: boolean; // Skip domains that already have certificates
|
||||
mongoDescriptor?: plugins.smartdata.IMongoDescriptor; // MongoDB config for SmartAcme
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,6 +144,10 @@ export interface ICertificateExpiring {
|
||||
*/
|
||||
export class Port80Handler extends plugins.EventEmitter {
|
||||
private domainCertificates: Map<string, IDomainCertificate>;
|
||||
// In-memory storage for ACME HTTP-01 challenge tokens
|
||||
private acmeHttp01Storage: Map<string, string> = new Map();
|
||||
// SmartAcme instance for certificate management
|
||||
private smartAcme: plugins.smartacme.SmartAcme | null = null;
|
||||
private server: plugins.http.Server | null = null;
|
||||
private acmeClient: plugins.acme.Client | null = null;
|
||||
private accountKey: string | null = null;
|
||||
@ -175,6 +195,20 @@ export class Port80Handler extends plugins.EventEmitter {
|
||||
console.log('Port80Handler is disabled, skipping start');
|
||||
return;
|
||||
}
|
||||
// Initialize SmartAcme for ACME challenge management (diskless HTTP handler)
|
||||
if (this.options.enabled) {
|
||||
if (!this.options.mongoDescriptor) {
|
||||
throw new ServerError('MongoDB descriptor is required for SmartAcme');
|
||||
}
|
||||
this.smartAcme = new plugins.smartacme.SmartAcme({
|
||||
accountEmail: this.options.contactEmail,
|
||||
environment: this.options.useProduction ? 'production' : 'integration',
|
||||
mongoDescriptor: this.options.mongoDescriptor,
|
||||
challengeHandlers: [ new DisklessHttp01Handler(this.acmeHttp01Storage) ],
|
||||
challengePriority: ['http-01'],
|
||||
});
|
||||
await this.smartAcme.start();
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
@ -640,19 +674,26 @@ export class Port80Handler extends plugins.EventEmitter {
|
||||
const { domainInfo, pattern } = domainMatch;
|
||||
const options = domainInfo.options;
|
||||
|
||||
// If the request is for an ACME HTTP-01 challenge, handle it
|
||||
if (req.url && req.url.startsWith('/.well-known/acme-challenge/') && (options.acmeMaintenance || options.acmeForward)) {
|
||||
// Check if we should forward ACME requests
|
||||
// Serve or forward ACME HTTP-01 challenge requests
|
||||
if (req.url && req.url.startsWith('/.well-known/acme-challenge/') && options.acmeMaintenance) {
|
||||
// Forward ACME requests if configured
|
||||
if (options.acmeForward) {
|
||||
this.forwardRequest(req, res, options.acmeForward, 'ACME challenge');
|
||||
return;
|
||||
}
|
||||
|
||||
// Only handle ACME challenges for non-glob patterns
|
||||
if (!this.isGlobPattern(pattern)) {
|
||||
this.handleAcmeChallenge(req, res, domain);
|
||||
return;
|
||||
// Serve challenge response from in-memory storage
|
||||
const token = req.url.split('/').pop() || '';
|
||||
const keyAuth = this.acmeHttp01Storage.get(token);
|
||||
if (keyAuth) {
|
||||
res.statusCode = 200;
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
res.end(keyAuth);
|
||||
console.log(`Served ACME challenge response for ${domain}`);
|
||||
} else {
|
||||
res.statusCode = 404;
|
||||
res.end('Challenge token not found');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we should forward non-ACME requests
|
||||
|
Reference in New Issue
Block a user