Commit | Line | Data |
---|---|---|
01f4001e | 1 | import { type IncomingMessage, Server, type ServerResponse } from 'node:http'; |
daa6505e JB |
2 | |
3 | import type { WebSocket } from 'ws'; | |
fe94fce0 | 4 | |
eb3abc4f JB |
5 | import { |
6 | AuthenticationType, | |
268a74bb | 7 | type ChargingStationData, |
e0b0ee21 JB |
8 | type ProcedureName, |
9 | type ProtocolRequest, | |
10 | type ProtocolResponse, | |
11 | type ProtocolVersion, | |
12 | type RequestPayload, | |
13 | type ResponsePayload, | |
268a74bb JB |
14 | type UIServerConfiguration, |
15 | } from '../../types'; | |
17bc43d7 | 16 | import { type AbstractUIService, UIServiceFactory } from '../internal'; |
8114d10e | 17 | |
fe94fce0 | 18 | export abstract class AbstractUIServer { |
32de5a57 | 19 | public readonly chargingStations: Map<string, ChargingStationData>; |
976d11ec JB |
20 | protected readonly httpServer: Server; |
21 | protected readonly responseHandlers: Map<string, ServerResponse | WebSocket>; | |
5e3cb728 | 22 | protected readonly uiServices: Map<ProtocolVersion, AbstractUIService>; |
fe94fce0 | 23 | |
eb3abc4f | 24 | public constructor(protected readonly uiServerConfiguration: UIServerConfiguration) { |
32de5a57 | 25 | this.chargingStations = new Map<string, ChargingStationData>(); |
daa6505e | 26 | this.httpServer = new Server(); |
94dc3080 | 27 | this.responseHandlers = new Map<string, ServerResponse | WebSocket>(); |
fe94fce0 JB |
28 | this.uiServices = new Map<ProtocolVersion, AbstractUIService>(); |
29 | } | |
30 | ||
852a4c5f JB |
31 | public buildProtocolRequest( |
32 | id: string, | |
33 | procedureName: ProcedureName, | |
34 | requestPayload: RequestPayload | |
5e3cb728 JB |
35 | ): ProtocolRequest { |
36 | return [id, procedureName, requestPayload]; | |
852a4c5f JB |
37 | } |
38 | ||
5e3cb728 JB |
39 | public buildProtocolResponse(id: string, responsePayload: ResponsePayload): ProtocolResponse { |
40 | return [id, responsePayload]; | |
852a4c5f JB |
41 | } |
42 | ||
daa6505e JB |
43 | public stop(): void { |
44 | this.chargingStations.clear(); | |
45 | } | |
46 | ||
a307349b JB |
47 | protected startHttpServer(): void { |
48 | if (this.httpServer.listening === false) { | |
49 | this.httpServer.listen(this.uiServerConfiguration.options); | |
50 | } | |
51 | } | |
52 | ||
143498c8 JB |
53 | protected registerProtocolVersionUIService(version: ProtocolVersion): void { |
54 | if (this.uiServices.has(version) === false) { | |
55 | this.uiServices.set(version, UIServiceFactory.getUIServiceImplementation(version, this)); | |
56 | } | |
57 | } | |
58 | ||
976d11ec JB |
59 | protected authenticate(req: IncomingMessage, next: (err?: Error) => void): void { |
60 | if (this.isBasicAuthEnabled() === true) { | |
61 | if (this.isValidBasicAuth(req) === false) { | |
62 | next(new Error('Unauthorized')); | |
63 | } | |
64 | next(); | |
65 | } | |
66 | next(); | |
67 | } | |
68 | ||
69 | private isBasicAuthEnabled(): boolean { | |
eb3abc4f JB |
70 | return ( |
71 | this.uiServerConfiguration.authentication?.enabled === true && | |
72 | this.uiServerConfiguration.authentication?.type === AuthenticationType.BASIC_AUTH | |
73 | ); | |
74 | } | |
75 | ||
976d11ec | 76 | private isValidBasicAuth(req: IncomingMessage): boolean { |
eb3abc4f JB |
77 | const authorizationHeader = req.headers.authorization ?? ''; |
78 | const authorizationToken = authorizationHeader.split(/\s+/).pop() ?? ''; | |
79 | const authentication = Buffer.from(authorizationToken, 'base64').toString(); | |
80 | const authenticationParts = authentication.split(/:/); | |
81 | const username = authenticationParts.shift(); | |
82 | const password = authenticationParts.join(':'); | |
83 | return ( | |
84 | this.uiServerConfiguration.authentication?.username === username && | |
85 | this.uiServerConfiguration.authentication?.password === password | |
86 | ); | |
87 | } | |
88 | ||
fe94fce0 | 89 | public abstract start(): void; |
5e3cb728 JB |
90 | public abstract sendRequest(request: ProtocolRequest): void; |
91 | public abstract sendResponse(response: ProtocolResponse): void; | |
92 | public abstract logPrefix( | |
93 | moduleName?: string, | |
94 | methodName?: string, | |
95 | prefixSuffix?: string | |
96 | ): string; | |
fe94fce0 | 97 | } |