1 import { type IncomingMessage
, Server
, type ServerResponse
} from
'http';
3 import type { WebSocket
} from
'ws';
5 import type { ChargingStationData
} from
'../../types/ChargingStationWorker';
6 import type { UIServerConfiguration
} from
'../../types/ConfigurationData';
15 } from
'../../types/UIProtocol';
16 import type AbstractUIService from
'./ui-services/AbstractUIService';
17 import UIServiceFactory from
'./ui-services/UIServiceFactory';
19 export abstract class AbstractUIServer
{
20 public readonly chargingStations
: Map
<string, ChargingStationData
>;
21 protected readonly httpServer
: Server
;
22 protected readonly responseHandlers
: Map
<string, ServerResponse
| WebSocket
>;
23 protected readonly uiServices
: Map
<ProtocolVersion
, AbstractUIService
>;
25 public constructor(protected readonly uiServerConfiguration
: UIServerConfiguration
) {
26 this.chargingStations
= new Map
<string, ChargingStationData
>();
27 this.httpServer
= new Server();
28 this.responseHandlers
= new Map
<string, ServerResponse
| WebSocket
>();
29 this.uiServices
= new Map
<ProtocolVersion
, AbstractUIService
>();
32 public buildProtocolRequest(
34 procedureName
: ProcedureName
,
35 requestPayload
: RequestPayload
37 return [id
, procedureName
, requestPayload
];
40 public buildProtocolResponse(id
: string, responsePayload
: ResponsePayload
): ProtocolResponse
{
41 return [id
, responsePayload
];
45 this.chargingStations
.clear();
48 protected registerProtocolVersionUIService(version
: ProtocolVersion
): void {
49 if (this.uiServices
.has(version
) === false) {
50 this.uiServices
.set(version
, UIServiceFactory
.getUIServiceImplementation(version
, this));
54 protected authenticate(req
: IncomingMessage
, next
: (err
?: Error) => void): void {
55 if (this.isBasicAuthEnabled() === true) {
56 if (this.isValidBasicAuth(req
) === false) {
57 next(new Error('Unauthorized'));
64 private isBasicAuthEnabled(): boolean {
66 this.uiServerConfiguration
.authentication
?.enabled
=== true &&
67 this.uiServerConfiguration
.authentication
?.type === AuthenticationType
.BASIC_AUTH
71 private isValidBasicAuth(req
: IncomingMessage
): boolean {
72 const authorizationHeader
= req
.headers
.authorization
?? '';
73 const authorizationToken
= authorizationHeader
.split(/\s
+/).pop() ?? '';
74 const authentication
= Buffer
.from(authorizationToken
, 'base64').toString();
75 const authenticationParts
= authentication
.split(/:/);
76 const username
= authenticationParts
.shift();
77 const password
= authenticationParts
.join(':');
79 this.uiServerConfiguration
.authentication
?.username
=== username
&&
80 this.uiServerConfiguration
.authentication
?.password
=== password
84 public abstract start(): void;
85 public abstract sendRequest(request
: ProtocolRequest
): void;
86 public abstract sendResponse(response
: ProtocolResponse
): void;
87 public abstract logPrefix(