X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=ui%2Fweb%2Fsrc%2Fcomposables%2FUIClient.ts;h=9522c59213c666a526d48927447024f3e8fc065a;hb=5218eec27c72bade7112c6b029d7d1eb1f42f871;hp=04b703e3e5e397eaabf4c8f37d191e9806761633;hpb=240fa4da80fd262158004eb576410d02afe0001f;p=e-mobility-charging-stations-simulator.git diff --git a/ui/web/src/composables/UIClient.ts b/ui/web/src/composables/UIClient.ts index 04b703e3..9522c592 100644 --- a/ui/web/src/composables/UIClient.ts +++ b/ui/web/src/composables/UIClient.ts @@ -1,5 +1,5 @@ import { useToast } from 'vue-toast-notification' -import { randomUUID } from './Utils' + import { ApplicationProtocol, AuthenticationType, @@ -12,6 +12,8 @@ import { type UIServerConfigurationSection } from '@/types' +import { randomUUID, validateUUID } from './Utils' + type ResponseHandler = { procedureName: ProcedureName resolve: (value: ResponsePayload | PromiseLike) => void @@ -22,15 +24,24 @@ export class UIClient { private static instance: UIClient | null = null private ws?: WebSocket - private responseHandlers: Map + private responseHandlers: Map< + `${string}-${string}-${string}-${string}-${string}`, + ResponseHandler + > private constructor(private uiServerConfiguration: UIServerConfigurationSection) { this.openWS() - this.responseHandlers = new Map() + this.responseHandlers = new Map< + `${string}-${string}-${string}-${string}-${string}`, + ResponseHandler + >() } - public static getInstance(uiServerConfiguration: UIServerConfigurationSection): UIClient { + public static getInstance(uiServerConfiguration?: UIServerConfigurationSection): UIClient { if (UIClient.instance === null) { + if (uiServerConfiguration == null) { + throw new Error('Cannot initialize UIClient if no configuration is provided') + } UIClient.instance = new UIClient(uiServerConfiguration) } return UIClient.instance @@ -53,6 +64,14 @@ export class UIClient { this.ws?.addEventListener(event, listener, options) } + public unregisterWSEventListener( + event: K, + listener: (event: WebSocketEventMap[K]) => void, + options?: boolean | AddEventListenerOptions + ) { + this.ws?.removeEventListener(event, listener, options) + } + public async simulatorState(): Promise { return this.sendRequest(ProcedureName.SIMULATOR_STATE, {}) } @@ -217,15 +236,30 @@ export class UIClient { } private responseHandler(messageEvent: MessageEvent): void { - const response = JSON.parse(messageEvent.data) as ProtocolResponse + let response: ProtocolResponse + try { + response = JSON.parse(messageEvent.data) + } catch (error) { + useToast().error('Invalid response JSON format') + console.error('Invalid response JSON format', error) + return + } - if (Array.isArray(response) === false) { - throw new Error(`Response not an array: ${JSON.stringify(response, undefined, 2)}`) + if (!Array.isArray(response)) { + useToast().error('Response not an array') + console.error('Response not an array:', response) + return } const [uuid, responsePayload] = response - if (this.responseHandlers.has(uuid) === true) { + if (!validateUUID(uuid)) { + useToast().error('Response UUID field is invalid') + console.error('Response UUID field is invalid:', response) + return + } + + if (this.responseHandlers.has(uuid)) { const { procedureName, resolve, reject } = this.responseHandlers.get(uuid)! switch (responsePayload.status) { case ResponseStatus.SUCCESS: