830476b41ec88b2d8d1bf2b8937462f9796724cc
[e-mobility-charging-stations-simulator.git] / src / charging-station / ui-server / UIServerFactory.ts
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 }