From 2bf962409626f42ce26f4288d5ab313374d6bdb8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Wed, 1 Apr 2026 16:23:42 +0200 Subject: [PATCH] refactor(ocpp): move isIdTagAuthorized into OCPPServiceOperations The circular dependency that motivated the separate IdTagAuthorization file no longer exists after auth module refactoring. Move the function to OCPPServiceOperations alongside other cross-stack transaction helpers and delete the standalone file. --- .../ocpp/1.6/OCPP16IncomingRequestService.ts | 2 +- .../ocpp/IdTagAuthorization.ts | 64 ------------------- .../ocpp/OCPPServiceOperations.ts | 63 +++++++++++++++++- src/charging-station/ocpp/index.ts | 2 +- .../ocpp/IdTagAuthorization.test.ts | 2 +- 5 files changed, 65 insertions(+), 68 deletions(-) delete mode 100644 src/charging-station/ocpp/IdTagAuthorization.ts diff --git a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts index eeb7655c..c387da4b 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -116,9 +116,9 @@ import { truncateId, } from '../../../utils/index.js' import { AuthContext } from '../auth/index.js' -import { isIdTagAuthorized } from '../IdTagAuthorization.js' import { OCPPConstants } from '../OCPPConstants.js' import { OCPPIncomingRequestService } from '../OCPPIncomingRequestService.js' +import { isIdTagAuthorized } from '../OCPPServiceOperations.js' import { buildMeterValue, createPayloadValidatorMap, diff --git a/src/charging-station/ocpp/IdTagAuthorization.ts b/src/charging-station/ocpp/IdTagAuthorization.ts deleted file mode 100644 index 8520c458..00000000 --- a/src/charging-station/ocpp/IdTagAuthorization.ts +++ /dev/null @@ -1,64 +0,0 @@ -import type { ChargingStation } from '../../charging-station/index.js' - -import { logger, truncateId } from '../../utils/index.js' -import { - AuthContext, - AuthenticationMethod, - AuthorizationStatus, - IdentifierType, - OCPPAuthServiceFactory, -} from './auth/index.js' - -export const isIdTagAuthorized = async ( - chargingStation: ChargingStation, - connectorId: number, - idTag: string, - context?: AuthContext -): Promise => { - try { - logger.debug( - `${chargingStation.logPrefix()} Authorizing idTag '${truncateId(idTag)}' on connector ${connectorId.toString()}` - ) - - const authService = OCPPAuthServiceFactory.getInstance(chargingStation) - - const authResult = await authService.authorize({ - allowOffline: false, - connectorId, - context: context ?? AuthContext.TRANSACTION_START, - identifier: { - type: IdentifierType.ID_TAG, - value: idTag, - }, - timestamp: new Date(), - }) - - logger.debug( - `${chargingStation.logPrefix()} Authorization result for idTag '${truncateId(idTag)}': ${authResult.status} using ${authResult.method} method` - ) - - if (authResult.status === AuthorizationStatus.ACCEPTED) { - const connectorStatus = chargingStation.getConnectorStatus(connectorId) - if (connectorStatus != null) { - switch (authResult.method) { - case AuthenticationMethod.CACHE: - case AuthenticationMethod.LOCAL_LIST: - case AuthenticationMethod.OFFLINE_FALLBACK: - connectorStatus.localAuthorizeIdTag = idTag - connectorStatus.idTagLocalAuthorized = true - break - case AuthenticationMethod.CERTIFICATE_BASED: - case AuthenticationMethod.NONE: - case AuthenticationMethod.REMOTE_AUTHORIZATION: - break - } - } - return true - } - - return false - } catch (error) { - logger.error(`${chargingStation.logPrefix()} Authorization failed`, error) - return false - } -} diff --git a/src/charging-station/ocpp/OCPPServiceOperations.ts b/src/charging-station/ocpp/OCPPServiceOperations.ts index 57db83df..0607932c 100644 --- a/src/charging-station/ocpp/OCPPServiceOperations.ts +++ b/src/charging-station/ocpp/OCPPServiceOperations.ts @@ -15,9 +15,16 @@ import { type StartTransactionResult, type StopTransactionResult, } from '../../types/index.js' -import { generateUUID, logger } from '../../utils/index.js' +import { generateUUID, logger, truncateId } from '../../utils/index.js' import { OCPP16ServiceUtils } from './1.6/OCPP16ServiceUtils.js' import { OCPP20ServiceUtils } from './2.0/OCPP20ServiceUtils.js' +import { + AuthContext, + AuthenticationMethod, + AuthorizationStatus as AuthStatus, + IdentifierType, + OCPPAuthServiceFactory, +} from './auth/index.js' import { mapStopReasonToOCPP20 } from './OCPPServiceUtils.js' /** @@ -267,3 +274,57 @@ export const buildBootNotificationRequest = ( return undefined } } + +export const isIdTagAuthorized = async ( + chargingStation: ChargingStation, + connectorId: number, + idTag: string, + context?: AuthContext +): Promise => { + try { + logger.debug( + `${chargingStation.logPrefix()} Authorizing idTag '${truncateId(idTag)}' on connector ${connectorId.toString()}` + ) + + const authService = OCPPAuthServiceFactory.getInstance(chargingStation) + + const authResult = await authService.authorize({ + allowOffline: false, + connectorId, + context: context ?? AuthContext.TRANSACTION_START, + identifier: { + type: IdentifierType.ID_TAG, + value: idTag, + }, + timestamp: new Date(), + }) + + logger.debug( + `${chargingStation.logPrefix()} Authorization result for idTag '${truncateId(idTag)}': ${authResult.status} using ${authResult.method} method` + ) + + if (authResult.status === AuthStatus.ACCEPTED) { + const connectorStatus = chargingStation.getConnectorStatus(connectorId) + if (connectorStatus != null) { + switch (authResult.method) { + case AuthenticationMethod.CACHE: + case AuthenticationMethod.LOCAL_LIST: + case AuthenticationMethod.OFFLINE_FALLBACK: + connectorStatus.localAuthorizeIdTag = idTag + connectorStatus.idTagLocalAuthorized = true + break + case AuthenticationMethod.CERTIFICATE_BASED: + case AuthenticationMethod.NONE: + case AuthenticationMethod.REMOTE_AUTHORIZATION: + break + } + } + return true + } + + return false + } catch (error) { + logger.error(`${chargingStation.logPrefix()} Authorization failed`, error) + return false + } +} diff --git a/src/charging-station/ocpp/index.ts b/src/charging-station/ocpp/index.ts index 56a33059..4d084d96 100644 --- a/src/charging-station/ocpp/index.ts +++ b/src/charging-station/ocpp/index.ts @@ -8,7 +8,6 @@ export { OCPP20ResponseService } from './2.0/OCPP20ResponseService.js' export { buildTransactionEvent, OCPP20ServiceUtils } from './2.0/OCPP20ServiceUtils.js' export { OCPP20VariableManager } from './2.0/OCPP20VariableManager.js' export { OCPPAuthServiceFactory } from './auth/index.js' -export { isIdTagAuthorized } from './IdTagAuthorization.js' export { OCPPConstants } from './OCPPConstants.js' export { OCPPIncomingRequestService } from './OCPPIncomingRequestService.js' export { OCPPRequestService } from './OCPPRequestService.js' @@ -16,6 +15,7 @@ export { createOCPPServices } from './OCPPServiceFactory.js' export { buildBootNotificationRequest, flushQueuedTransactionMessages, + isIdTagAuthorized, startTransactionOnConnector, stopRunningTransactions, stopTransactionOnConnector, diff --git a/tests/charging-station/ocpp/IdTagAuthorization.test.ts b/tests/charging-station/ocpp/IdTagAuthorization.test.ts index 7e2c408b..c556dab8 100644 --- a/tests/charging-station/ocpp/IdTagAuthorization.test.ts +++ b/tests/charging-station/ocpp/IdTagAuthorization.test.ts @@ -20,7 +20,7 @@ import { AuthorizationStatus, OCPPAuthServiceFactory, } from '../../../src/charging-station/ocpp/auth/index.js' -import { isIdTagAuthorized } from '../../../src/charging-station/ocpp/IdTagAuthorization.js' +import { isIdTagAuthorized } from '../../../src/charging-station/ocpp/OCPPServiceOperations.js' import { OCPPVersion } from '../../../src/types/index.js' import { standardCleanup } from '../../helpers/TestLifecycleHelpers.js' import { createMockChargingStation } from '../ChargingStationTestUtils.js' -- 2.43.0