| 1 | import chalk from 'chalk' |
| 2 | |
| 3 | import type { AbstractUIServer } from './AbstractUIServer.js' |
| 4 | |
| 5 | import { BaseError } from '../../exception/index.js' |
| 6 | import { |
| 7 | ApplicationProtocol, |
| 8 | ApplicationProtocolVersion, |
| 9 | AuthenticationType, |
| 10 | ConfigurationSection, |
| 11 | type UIServerConfiguration, |
| 12 | } from '../../types/index.js' |
| 13 | import { logger, logPrefix } from '../../utils/index.js' |
| 14 | import { UIHttpServer } from './UIHttpServer.js' |
| 15 | import { isLoopback } from './UIServerUtils.js' |
| 16 | import { UIWebSocketServer } from './UIWebSocketServer.js' |
| 17 | |
| 18 | // eslint-disable-next-line @typescript-eslint/no-extraneous-class |
| 19 | export class UIServerFactory { |
| 20 | private static readonly logPrefix = (modName?: string, methodName?: string): string => { |
| 21 | const logMsgPrefix = 'UI Server' |
| 22 | const logMsg = |
| 23 | modName != null && methodName != null |
| 24 | ? ` ${logMsgPrefix} | ${modName}.${methodName}:` |
| 25 | : ` ${logMsgPrefix} |` |
| 26 | return logPrefix(logMsg) |
| 27 | } |
| 28 | |
| 29 | private constructor () { |
| 30 | // This is intentional |
| 31 | } |
| 32 | |
| 33 | public static getUIServerImplementation ( |
| 34 | uiServerConfiguration: UIServerConfiguration |
| 35 | ): AbstractUIServer { |
| 36 | if ( |
| 37 | uiServerConfiguration.authentication?.enabled === true && |
| 38 | !Object.values(AuthenticationType).includes(uiServerConfiguration.authentication.type) |
| 39 | ) { |
| 40 | throw new BaseError( |
| 41 | `Unknown authentication type '${uiServerConfiguration.authentication.type}' in '${ConfigurationSection.uiServer}' configuration section` |
| 42 | ) |
| 43 | } |
| 44 | if ( |
| 45 | uiServerConfiguration.type === ApplicationProtocol.HTTP && |
| 46 | uiServerConfiguration.authentication?.enabled === true && |
| 47 | uiServerConfiguration.authentication.type === AuthenticationType.PROTOCOL_BASIC_AUTH |
| 48 | ) { |
| 49 | throw new BaseError( |
| 50 | `'${uiServerConfiguration.authentication.type}' authentication type with application protocol type '${uiServerConfiguration.type}' is not supported in '${ConfigurationSection.uiServer}' configuration section` |
| 51 | ) |
| 52 | } |
| 53 | if ( |
| 54 | uiServerConfiguration.authentication?.enabled !== true && |
| 55 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion |
| 56 | !isLoopback(uiServerConfiguration.options!.host!) |
| 57 | ) { |
| 58 | const logMsg = `Non loopback address in '${ConfigurationSection.uiServer}' configuration section without authentication enabled. This is not recommended` |
| 59 | logger.warn(`${UIServerFactory.logPrefix()} ${logMsg}`) |
| 60 | console.warn(chalk.yellow(logMsg)) |
| 61 | } |
| 62 | if ( |
| 63 | uiServerConfiguration.type === ApplicationProtocol.WS && |
| 64 | uiServerConfiguration.version !== ApplicationProtocolVersion.VERSION_11 |
| 65 | ) { |
| 66 | const logMsg = `Only version ${ApplicationProtocolVersion.VERSION_11} with application protocol type '${uiServerConfiguration.type}' is supported in '${ConfigurationSection.uiServer}' configuration section. Falling back to version ${ApplicationProtocolVersion.VERSION_11}` |
| 67 | logger.warn(`${UIServerFactory.logPrefix()} ${logMsg}`) |
| 68 | console.warn(chalk.yellow(logMsg)) |
| 69 | uiServerConfiguration.version = ApplicationProtocolVersion.VERSION_11 |
| 70 | } |
| 71 | switch (uiServerConfiguration.type) { |
| 72 | case ApplicationProtocol.HTTP: |
| 73 | return new UIHttpServer(uiServerConfiguration) |
| 74 | case ApplicationProtocol.WS: |
| 75 | default: |
| 76 | if ( |
| 77 | !Object.values(ApplicationProtocol).includes( |
| 78 | uiServerConfiguration.type as ApplicationProtocol |
| 79 | ) |
| 80 | ) { |
| 81 | // eslint-disable-next-line @typescript-eslint/restrict-template-expressions |
| 82 | const logMsg = `Unknown application protocol type '${uiServerConfiguration.type}' in '${ |
| 83 | ConfigurationSection.uiServer |
| 84 | // eslint-disable-next-line @typescript-eslint/no-base-to-string |
| 85 | }' configuration section from values '${ApplicationProtocol.toString()}', defaulting to '${ |
| 86 | ApplicationProtocol.WS |
| 87 | }'` |
| 88 | logger.warn(`${UIServerFactory.logPrefix()} ${logMsg}`) |
| 89 | console.warn(logMsg) |
| 90 | } |
| 91 | return new UIWebSocketServer(uiServerConfiguration) |
| 92 | } |
| 93 | } |
| 94 | } |