import * as plugins from './plugins.js'; import * as paths from './paths.js'; import { Cloudly } from './classes.cloudly.js'; import { logger } from './logger.js'; /** * handles incoming requests from CI to deploy new versions of apps */ export class CloudlyServer { /** * a reference to the cloudly instance */ public cloudlyRef: Cloudly; public additionalHandlers: plugins.typedserver.servertools.Handler[] = []; /** * the smartexpress server handling the actual requests */ public typedServer: plugins.typedserver.TypedServer; public typedsocketServer: plugins.typedsocket.TypedSocket; /** * typedrouter * @param cloudlyArg */ public typedrouter = new plugins.typedrequest.TypedRouter(); constructor(cloudlyArg: Cloudly) { this.cloudlyRef = cloudlyArg; this.cloudlyRef.typedrouter.addTypedRouter(this.typedrouter); } // ========= // LIFECYCLE // ========= /** * init the reception instance */ public async start() { logger.log('info', `cloudly domain is ${this.cloudlyRef.config.data.publicUrl}`); let sslCert: plugins.smartacme.Cert; if (this.cloudlyRef.config.data.sslMode === 'letsencrypt') { logger.log('info', `Using letsencrypt for ssl mode. Trying to obtain a certificate...`); logger.log('info', `This might take 10 minutes...`); sslCert = await this.cloudlyRef.letsencryptConnector.getCertificateForDomain( this.cloudlyRef.config.data.publicUrl ); logger.log( 'success', `Successfully obtained certificate for cloudly domain ${this.cloudlyRef.config.data.publicUrl}` ); } else if (this.cloudlyRef.config.data.sslMode === 'external') { logger.log( 'info', `Using external certificate for ssl mode, meaning cloudly is not in charge of ssl termination.` ); } interface IRequestGuardData { req: plugins.typedserver.Request; res: plugins.typedserver.Response; } // guards const guardIp = new plugins.smartguard.Guard(async (dataArg) => { if (true) { return true; } else { dataArg.res.status(500); dataArg.res.send(`Not allowed to perform this operation!`); dataArg.res.end(); return false; } }); // server this.typedServer = new plugins.typedserver.TypedServer({ cors: true, forceSsl: false, port: this.cloudlyRef.config.data.publicPort, ...(sslCert ? { privateKey: sslCert.privateKey, publicKey: sslCert.publicKey, } : {}), injectReload: true, serveDir: paths.distServeDir, watch: true, enableCompression: true, preferredCompressionMethod: 'gzip', }); this.typedServer.typedrouter.addTypedRouter(this.typedrouter); this.typedServer.server.addRoute( '/curlfresh/:scriptname', this.cloudlyRef.serverManager.curlfreshInstance.handler ); await this.typedServer.start(); } /** * stop the reception instance */ public async stop() { await this.typedServer.stop(); } }