import { EndpointType } from "$lib/enums/endpoints" import type { NginxProtocol } from "$lib/enums/protocols" import { doesFileExists } from "$lib/utils/filesystem-utils" import { isPortAvailable, validatePort } from "$lib/utils/ports-utils" import type { init } from "../../hooks.server" import type { IEndpoint } from "./endpoints" // TODO: inherit from a super class export interface ISSLTerminationBroker { /** * Initialize the Broker and everything related to it */ init(): Promise // Creation should throw if something goes wrong // with reasons why createSSLTerminationSimple( name: string, servicePort: number, serviceEndpoint: string, certificateURI: string, privateKeyURI: string ): Promise createSSLTerminationComplete( name: string, sslPort: number, clearPort: number, servicePort: number, serviceEndpoint: string, certificateURI: string, privateKeyURI: string ): Promise // Getting endpoints may be null, react over them getSSLTerminationByName( name: string ): Promise // Throw if something goes wrong modifySSLTerminationByName( name: string, changes: SSLTerminationChanges ): Promise deleteSSLTerminationByName( name: string ): Promise getAllSSLTerminations(): Promise } /** * This class represents an SSL Termination Endpoint. * * While it's possible to create it directly, it is * discouraged in favor of the Factory methods as it does * more checks than this class */ export class SSLTermination implements IEndpoint { private static _type: EndpointType = EndpointType.SSL_TERMINATION public path: string public hash: string public name: string public sslPort: number public clearPort: number public servicePort: number public serviceEndpoint: string public protocol: NginxProtocol public certificateURI: string public privateKeyURI: string public get type() { return SSLTermination._type } constructor( name: string, path: string, hash: string, sslPort: number, clearPort: number, servicePort: number, serviceEndpoint: string, protocol: NginxProtocol, certificateURI: string, privateKeyURI: string ) { validatePort(sslPort) validatePort(clearPort) validatePort(servicePort) this.name = name this.path = path this.hash = hash this.sslPort = sslPort this.clearPort = clearPort this.servicePort = servicePort this.serviceEndpoint = serviceEndpoint this.protocol = protocol this.certificateURI = certificateURI this.privateKeyURI = privateKeyURI } } type SSLTerminationChanges = { name?: string, sslPort?: number, clearPort?: number, servicePort?: number, serviceEndpoint?: string, protocol?: NginxProtocol, certificateURI?: string, privateKeyURI?: string } export class SSLTerminationEndpointApp { private static initialized: boolean = false private static broker: ISSLTerminationBroker public static get ready() { return SSLTerminationEndpointApp.initialized } public static init(broker: ISSLTerminationBroker) { SSLTerminationEndpointApp.assureNotInitialized() SSLTerminationEndpointApp.broker = broker broker.init() SSLTerminationEndpointApp.initialized = true } // Creation should throw if something goes wrong // with reasons why public static async createSSLTerminationSimple( name: string, servicePort: number, serviceEndpoint: string, certificateURI: string, privateKeyURI: string ): Promise { SSLTerminationEndpointApp.assureInitialized() return await this.broker.createSSLTerminationSimple( name, servicePort, serviceEndpoint, certificateURI, privateKeyURI ) } public static async createSSLTerminationComplete( name: string, sslPort: number, clearPort: number, servicePort: number, serviceEndpoint: string, certificateURI: string, privateKeyURI: string ): Promise { SSLTerminationEndpointApp.assureInitialized() return await this.broker.createSSLTerminationComplete( name, sslPort, clearPort, servicePort, serviceEndpoint, certificateURI, privateKeyURI ) } // Getting endpoints may be null, react over them public static async getSSLTerminationByName( name: string ): Promise { SSLTerminationEndpointApp.assureInitialized() return await this.broker.getSSLTerminationByName( name ) } // Throw if something goes wrong public static async modifySSLTerminationByName( name: string, changes: SSLTerminationChanges ): Promise { SSLTerminationEndpointApp.assureInitialized() return await this.broker.modifySSLTerminationByName( name, changes ) } public static async deleteSSLTerminationByName( name: string ): Promise { SSLTerminationEndpointApp.assureInitialized() return await this.broker.deleteSSLTerminationByName( name ) } public static async getAllSSLTerminations(): Promise { SSLTerminationEndpointApp.assureInitialized() return await this.broker.getAllSSLTerminations() } private static assureNotInitialized() { if (SSLTerminationEndpointApp.initialized) { // UGLY: more specific throw new Error("SSLTerminationEndpointApp has been already initialized") } } private static assureInitialized() { if (SSLTerminationEndpointApp.initialized) { // UGLY: more specific throw new Error("SSLTerminationEndpointApp has not been initialized yet") } } }