build(deps-dev): apply updates
[e-mobility-charging-stations-simulator.git] / src / charging-station / ui-server / UIServerFactory.ts
index c4006b0396d96c8d5ad50e902bfedf8ea2743c65..cf176bdc0403d2be85890204ba7b67e06f9b6c4a 100644 (file)
@@ -1,33 +1,92 @@
-import chalk from 'chalk';
+import chalk from 'chalk'
 
-import type { AbstractUIServer } from './AbstractUIServer';
-import { UIHttpServer } from './UIHttpServer';
-import { UIServerUtils } from './UIServerUtils';
-import { UIWebSocketServer } from './UIWebSocketServer';
-import { ApplicationProtocol, type UIServerConfiguration } from '../../types';
+import { BaseError } from '../../exception/index.js'
+import {
+  ApplicationProtocol,
+  ApplicationProtocolVersion,
+  AuthenticationType,
+  ConfigurationSection,
+  type UIServerConfiguration
+} from '../../types/index.js'
+import { logger, logPrefix } from '../../utils/index.js'
+import type { AbstractUIServer } from './AbstractUIServer.js'
+import { UIHttpServer } from './UIHttpServer.js'
+import { isLoopback } from './UIServerUtils.js'
+import { UIWebSocketServer } from './UIWebSocketServer.js'
 
+// eslint-disable-next-line @typescript-eslint/no-extraneous-class
 export class UIServerFactory {
-  private constructor() {
+  private constructor () {
     // This is intentional
   }
 
-  public static getUIServerImplementation(
-    uiServerConfiguration: UIServerConfiguration,
-  ): AbstractUIServer | null {
-    if (UIServerUtils.isLoopback(uiServerConfiguration.options!.host!) === false) {
-      console.warn(
-        chalk.yellow(
-          'Loopback address not detected in UI server configuration. This is not recommended.',
-        ),
-      );
+  public static getUIServerImplementation (
+    uiServerConfiguration: UIServerConfiguration
+  ): AbstractUIServer {
+    if (
+      uiServerConfiguration.authentication?.enabled === true &&
+      !Object.values(AuthenticationType).includes(uiServerConfiguration.authentication.type)
+    ) {
+      throw new BaseError(
+        `Unknown authentication type '${uiServerConfiguration.authentication.type}' in '${ConfigurationSection.uiServer}' configuration section`
+      )
+    }
+    if (
+      uiServerConfiguration.type === ApplicationProtocol.HTTP &&
+      uiServerConfiguration.authentication?.enabled === true &&
+      uiServerConfiguration.authentication.type === AuthenticationType.PROTOCOL_BASIC_AUTH
+    ) {
+      throw new BaseError(
+        `'${uiServerConfiguration.authentication.type}' authentication type with application protocol type '${uiServerConfiguration.type}' is not supported in '${ConfigurationSection.uiServer}' configuration section`
+      )
+    }
+    if (
+      uiServerConfiguration.authentication?.enabled !== true &&
+      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+      !isLoopback(uiServerConfiguration.options!.host!)
+    ) {
+      const logMsg = `Non loopback address in '${ConfigurationSection.uiServer}' configuration section without authentication enabled. This is not recommended`
+      logger.warn(`${UIServerFactory.logPrefix()} ${logMsg}`)
+      console.warn(chalk.yellow(logMsg))
+    }
+    if (
+      uiServerConfiguration.type === ApplicationProtocol.WS &&
+      uiServerConfiguration.version !== ApplicationProtocolVersion.VERSION_11
+    ) {
+      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}`
+      logger.warn(`${UIServerFactory.logPrefix()} ${logMsg}`)
+      console.warn(chalk.yellow(logMsg))
+      uiServerConfiguration.version = ApplicationProtocolVersion.VERSION_11
     }
     switch (uiServerConfiguration.type) {
-      case ApplicationProtocol.WS:
-        return new UIWebSocketServer(uiServerConfiguration);
       case ApplicationProtocol.HTTP:
-        return new UIHttpServer(uiServerConfiguration);
+        return new UIHttpServer(uiServerConfiguration)
+      case ApplicationProtocol.WS:
       default:
-        return null;
+        if (
+          !Object.values(ApplicationProtocol).includes(
+            uiServerConfiguration.type as ApplicationProtocol
+          )
+        ) {
+          const logMsg = `Unknown application protocol type '${uiServerConfiguration.type}' in '${
+            ConfigurationSection.uiServer
+            // eslint-disable-next-line @typescript-eslint/no-base-to-string
+          }' configuration section from values '${ApplicationProtocol.toString()}', defaulting to '${
+            ApplicationProtocol.WS
+          }'`
+          logger.warn(`${UIServerFactory.logPrefix()} ${logMsg}`)
+          console.warn(logMsg)
+        }
+        return new UIWebSocketServer(uiServerConfiguration)
     }
   }
+
+  private static readonly logPrefix = (modName?: string, methodName?: string): string => {
+    const logMsgPrefix = 'UI Server'
+    const logMsg =
+      modName != null && methodName != null
+        ? ` ${logMsgPrefix} | ${modName}.${methodName}:`
+        : ` ${logMsgPrefix} |`
+    return logPrefix(logMsg)
+  }
 }