import * as plugins from '../../plugins.js'; import type { IDomainOptions, IAcmeOptions } from '../models/common-types.js'; /** * Collection of validation utilities for configuration and domain options */ export class ValidationUtils { /** * Validates domain configuration options * * @param domainOptions The domain options to validate * @returns An object with validation result and error message if invalid */ public static validateDomainOptions(domainOptions: IDomainOptions): { isValid: boolean; error?: string } { if (!domainOptions) { return { isValid: false, error: 'Domain options cannot be null or undefined' }; } if (!domainOptions.domainName) { return { isValid: false, error: 'Domain name is required' }; } // Check domain pattern if (!this.isValidDomainName(domainOptions.domainName)) { return { isValid: false, error: `Invalid domain name: ${domainOptions.domainName}` }; } // Validate forward config if provided if (domainOptions.forward) { if (!domainOptions.forward.ip) { return { isValid: false, error: 'Forward IP is required when forward is specified' }; } if (!domainOptions.forward.port) { return { isValid: false, error: 'Forward port is required when forward is specified' }; } if (!this.isValidPort(domainOptions.forward.port)) { return { isValid: false, error: `Invalid forward port: ${domainOptions.forward.port}` }; } } // Validate ACME forward config if provided if (domainOptions.acmeForward) { if (!domainOptions.acmeForward.ip) { return { isValid: false, error: 'ACME forward IP is required when acmeForward is specified' }; } if (!domainOptions.acmeForward.port) { return { isValid: false, error: 'ACME forward port is required when acmeForward is specified' }; } if (!this.isValidPort(domainOptions.acmeForward.port)) { return { isValid: false, error: `Invalid ACME forward port: ${domainOptions.acmeForward.port}` }; } } return { isValid: true }; } /** * Validates ACME configuration options * * @param acmeOptions The ACME options to validate * @returns An object with validation result and error message if invalid */ public static validateAcmeOptions(acmeOptions: IAcmeOptions): { isValid: boolean; error?: string } { if (!acmeOptions) { return { isValid: false, error: 'ACME options cannot be null or undefined' }; } if (acmeOptions.enabled) { if (!acmeOptions.accountEmail) { return { isValid: false, error: 'Account email is required when ACME is enabled' }; } if (!this.isValidEmail(acmeOptions.accountEmail)) { return { isValid: false, error: `Invalid email: ${acmeOptions.accountEmail}` }; } if (acmeOptions.port && !this.isValidPort(acmeOptions.port)) { return { isValid: false, error: `Invalid ACME port: ${acmeOptions.port}` }; } if (acmeOptions.httpsRedirectPort && !this.isValidPort(acmeOptions.httpsRedirectPort)) { return { isValid: false, error: `Invalid HTTPS redirect port: ${acmeOptions.httpsRedirectPort}` }; } if (acmeOptions.renewThresholdDays && acmeOptions.renewThresholdDays < 1) { return { isValid: false, error: 'Renew threshold days must be greater than 0' }; } if (acmeOptions.renewCheckIntervalHours && acmeOptions.renewCheckIntervalHours < 1) { return { isValid: false, error: 'Renew check interval hours must be greater than 0' }; } } return { isValid: true }; } /** * Validates a port number * * @param port The port to validate * @returns true if the port is valid, false otherwise */ public static isValidPort(port: number): boolean { return typeof port === 'number' && port > 0 && port <= 65535 && Number.isInteger(port); } /** * Validates a domain name * * @param domain The domain name to validate * @returns true if the domain name is valid, false otherwise */ public static isValidDomainName(domain: string): boolean { if (!domain || typeof domain !== 'string') { return false; } // Wildcard domain check (*.example.com) if (domain.startsWith('*.')) { domain = domain.substring(2); } // Simple domain validation pattern const domainPattern = /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/; return domainPattern.test(domain); } /** * Validates an email address * * @param email The email to validate * @returns true if the email is valid, false otherwise */ public static isValidEmail(email: string): boolean { if (!email || typeof email !== 'string') { return false; } // Basic email validation pattern const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailPattern.test(email); } /** * Validates a certificate format (PEM) * * @param cert The certificate content to validate * @returns true if the certificate appears to be in PEM format, false otherwise */ public static isValidCertificate(cert: string): boolean { if (!cert || typeof cert !== 'string') { return false; } return cert.includes('-----BEGIN CERTIFICATE-----') && cert.includes('-----END CERTIFICATE-----'); } /** * Validates a private key format (PEM) * * @param key The private key content to validate * @returns true if the key appears to be in PEM format, false otherwise */ public static isValidPrivateKey(key: string): boolean { if (!key || typeof key !== 'string') { return false; } return key.includes('-----BEGIN PRIVATE KEY-----') && key.includes('-----END PRIVATE KEY-----'); } }