]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commitdiff
fix(ocpp2): use convertToDate() for all incoming date fields in handlers
authorJérôme Benoit <jerome.benoit@sap.com>
Tue, 17 Mar 2026 12:21:30 +0000 (13:21 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Tue, 17 Mar 2026 12:21:30 +0000 (13:21 +0100)
Replace raw new Date(string) and direct string comparisons with
convertToDate() for date fields in incoming OCPP 2.0 payloads:
- validateChargingProfile: validFrom/validTo comparisons
- validateChargingSchedule: startSchedule comparisons
- simulateFirmwareUpdateLifecycle: retrieveDateTime/installDateTime
- handleResponseHeartbeat: currentTime display
- OCPP20CertificateManager: cert.validFrom/validTo validation

src/charging-station/ocpp/2.0/OCPP20CertificateManager.ts
src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts
src/charging-station/ocpp/2.0/OCPP20ResponseService.ts

index ea0a3a1f35af84f7af54c6452ee0803cd751f351..e255cb2ea0df8ac83d671fab55e7d9a6c695d165 100644 (file)
@@ -15,7 +15,7 @@ import {
   HashAlgorithmEnumType,
   InstallCertificateUseEnumType,
 } from '../../../types/ocpp/2.0/Common.js'
-import { getErrorMessage } from '../../../utils/index.js'
+import { convertToDate, getErrorMessage } from '../../../utils/index.js'
 
 /**
  * Interface for ChargingStation with certificate manager
@@ -471,10 +471,12 @@ export class OCPP20CertificateManager {
       }
       const cert = new X509Certificate(firstCertMatch[0])
       const now = new Date()
-      if (now < new Date(cert.validFrom)) {
+      const validFromDate = convertToDate(cert.validFrom)
+      const validToDate = convertToDate(cert.validTo)
+      if (validFromDate != null && now < validFromDate) {
         return { reason: 'Certificate is not yet valid', valid: false }
       }
-      if (now > new Date(cert.validTo)) {
+      if (validToDate != null && now > validToDate) {
         return { reason: 'Certificate has expired', valid: false }
       }
       if (!cert.issuer.trim()) {
index 67492407204398acacbdc098ce5419268e66834e..a06a56d0a88916c7f4a7787a8cb58dd8feb6dbc4 100644 (file)
@@ -127,7 +127,14 @@ import {
   OCPP20ChargingRateUnitEnumType,
   OCPP20ReasonEnumType,
 } from '../../../types/ocpp/2.0/Transaction.js'
-import { Constants, generateUUID, logger, sleep, validateUUID } from '../../../utils/index.js'
+import {
+  Constants,
+  convertToDate,
+  generateUUID,
+  logger,
+  sleep,
+  validateUUID,
+} from '../../../utils/index.js'
 import { getConfigurationKey } from '../../ConfigurationKeyUtils.js'
 import {
   getIdTagsFile,
@@ -3404,7 +3411,7 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService {
 
     // C12: If retrieveDateTime is in the future, send DownloadScheduled and wait
     const now = Date.now()
-    const retrieveTime = new Date(retrieveDateTime).getTime()
+    const retrieveTime = convertToDate(retrieveDateTime)?.getTime() ?? now
     if (retrieveTime > now) {
       await this.sendFirmwareStatusNotification(
         chargingStation,
@@ -3456,8 +3463,8 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService {
 
     // C12: If installDateTime is in the future, send InstallScheduled and wait
     if (installDateTime != null) {
-      const installTime = new Date(installDateTime).getTime()
       const currentTime = Date.now()
+      const installTime = convertToDate(installDateTime)?.getTime() ?? currentTime
       if (installTime > currentTime) {
         await this.sendFirmwareStatusNotification(
           chargingStation,
@@ -3760,8 +3767,10 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService {
     }
 
     const now = new Date()
-    if (chargingProfile.validFrom && chargingProfile.validTo) {
-      if (chargingProfile.validFrom >= chargingProfile.validTo) {
+    const validFromDate = convertToDate(chargingProfile.validFrom)
+    const validToDate = convertToDate(chargingProfile.validTo)
+    if (validFromDate && validToDate) {
+      if (validFromDate >= validToDate) {
         logger.warn(
           `${chargingStation.logPrefix()} ${moduleName}.validateChargingProfile: validFrom must be before validTo`
         )
@@ -3769,7 +3778,7 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService {
       }
     }
 
-    if (chargingProfile.validTo && chargingProfile.validTo <= now) {
+    if (validToDate && validToDate <= now) {
       logger.warn(
         `${chargingStation.logPrefix()} ${moduleName}.validateChargingProfile: Charging profile already expired`
       )
@@ -3942,22 +3951,18 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService {
       return false
     }
 
-    if (
-      schedule.startSchedule &&
-      chargingProfile.validFrom &&
-      schedule.startSchedule < chargingProfile.validFrom
-    ) {
+    const startScheduleDate = convertToDate(schedule.startSchedule)
+    const validFromDate = convertToDate(chargingProfile.validFrom)
+    const validToDate = convertToDate(chargingProfile.validTo)
+
+    if (startScheduleDate != null && validFromDate != null && startScheduleDate < validFromDate) {
       logger.warn(
         `${chargingStation.logPrefix()} ${moduleName}.validateChargingSchedule: Schedule start time cannot be before profile validFrom`
       )
       return false
     }
 
-    if (
-      schedule.startSchedule &&
-      chargingProfile.validTo &&
-      schedule.startSchedule >= chargingProfile.validTo
-    ) {
+    if (startScheduleDate != null && validToDate != null && startScheduleDate >= validToDate) {
       logger.warn(
         `${chargingStation.logPrefix()} ${moduleName}.validateChargingSchedule: Schedule start time must be before profile validTo`
       )
index 3ab8940a9a3df245c2397af0f95d68b322c337cf..118d79d3a9de0c8a151c3a9c6431fcb1ef38268e 100644 (file)
@@ -25,7 +25,7 @@ import {
   type ResponseHandler,
 } from '../../../types/index.js'
 import { OCPP20AuthorizationStatusEnumType } from '../../../types/ocpp/2.0/Transaction.js'
-import { logger } from '../../../utils/index.js'
+import { convertToDate, logger } from '../../../utils/index.js'
 import { OCPPResponseService } from '../OCPPResponseService.js'
 import { OCPP20ServiceUtils } from './OCPP20ServiceUtils.js'
 
@@ -214,7 +214,7 @@ export class OCPP20ResponseService extends OCPPResponseService {
     payload: OCPP20HeartbeatResponse
   ): void {
     logger.debug(
-      `${chargingStation.logPrefix()} ${moduleName}.handleResponseHeartbeat: Heartbeat response received at ${payload.currentTime.toISOString()}`
+      `${chargingStation.logPrefix()} ${moduleName}.handleResponseHeartbeat: Heartbeat response received at ${convertToDate(payload.currentTime)?.toISOString() ?? 'unknown'}`
     )
   }