8552a572f4bf08ab3134da682f3c444f2aa54773
1 import { type IncomingMessage
, Server
, type ServerResponse
} from
'node:http';
3 import type { WebSocket
} from
'ws';
5 import type { AbstractUIService
} from
'./ui-services/AbstractUIService';
6 import { UIServiceFactory
} from
'./ui-services/UIServiceFactory';
7 import { BaseError
} from
'../../exception';
10 type ChargingStationData
,
13 type ProtocolResponse
,
17 type UIServerConfiguration
,
20 export abstract class AbstractUIServer
{
21 public readonly chargingStations
: Map
<string, ChargingStationData
>;
22 protected readonly httpServer
: Server
;
23 protected readonly responseHandlers
: Map
<string, ServerResponse
| WebSocket
>;
24 protected readonly uiServices
: Map
<ProtocolVersion
, AbstractUIService
>;
26 public constructor(protected readonly uiServerConfiguration
: UIServerConfiguration
) {
27 this.chargingStations
= new Map
<string, ChargingStationData
>();
28 this.httpServer
= new Server();
29 this.responseHandlers
= new Map
<string, ServerResponse
| WebSocket
>();
30 this.uiServices
= new Map
<ProtocolVersion
, AbstractUIService
>();
33 public buildProtocolRequest(
35 procedureName
: ProcedureName
,
36 requestPayload
: RequestPayload
38 return [id
, procedureName
, requestPayload
];
41 public buildProtocolResponse(id
: string, responsePayload
: ResponsePayload
): ProtocolResponse
{
42 return [id
, responsePayload
];
46 this.chargingStations
.clear();
49 public async sendRequestOnBroadcastChannel(request
: ProtocolRequest
): Promise
<ProtocolResponse
> {
50 const protocolVersion
= ProtocolVersion
['0.0.1'];
51 this.registerProtocolVersionUIService(protocolVersion
);
52 return this.uiServices
.get(protocolVersion
)?.requestHandler(request
);
55 protected startHttpServer(): void {
56 if (this.httpServer
.listening
=== false) {
57 this.httpServer
.listen(this.uiServerConfiguration
.options
);
61 protected registerProtocolVersionUIService(version
: ProtocolVersion
): void {
62 if (this.uiServices
.has(version
) === false) {
63 this.uiServices
.set(version
, UIServiceFactory
.getUIServiceImplementation(version
, this));
67 protected authenticate(req
: IncomingMessage
, next
: (err
?: Error) => void): void {
68 if (this.isBasicAuthEnabled() === true) {
69 if (this.isValidBasicAuth(req
) === false) {
70 next(new BaseError('Unauthorized'));
77 private isBasicAuthEnabled(): boolean {
79 this.uiServerConfiguration
.authentication
?.enabled
=== true &&
80 this.uiServerConfiguration
.authentication
?.type === AuthenticationType
.BASIC_AUTH
84 private isValidBasicAuth(req
: IncomingMessage
): boolean {
85 const authorizationHeader
= req
.headers
.authorization
?? '';
86 const authorizationToken
= authorizationHeader
.split(/\s
+/).pop() ?? '';
87 const authentication
= Buffer
.from(authorizationToken
, 'base64').toString();
88 const authenticationParts
= authentication
.split(/:/);
89 const username
= authenticationParts
.shift();
90 const password
= authenticationParts
.join(':');
92 this.uiServerConfiguration
.authentication
?.username
=== username
&&
93 this.uiServerConfiguration
.authentication
?.password
=== password
97 public abstract start(): void;
98 public abstract sendRequest(request
: ProtocolRequest
): void;
99 public abstract sendResponse(response
: ProtocolResponse
): void;
100 public abstract logPrefix(
103 prefixSuffix
?: string