Fixed email in lower case in OCPI
MODIFY
src/client/ocpi/CpoOCPIClient.ts
src/client/ocpi/CpoOCPIClient.ts
@@ -6,6 +6,7 @@ import { OCPIAllowed, OCPIAuthorizationInfo } from '../../types/ocpi/OCPIAuthori
import { OCPIAuthMethod, OCPISession, OCPISessionStatus } from '../../types/ocpi/OCPISession';
import { OCPICapability, OCPIEvse, OCPIEvseStatus } from '../../types/ocpi/OCPIEvse';
import { OCPILocation, OCPILocationOptions, OCPILocationReference, OCPILocationType } from '../../types/ocpi/OCPILocation';
+import User, { UserRole, UserStatus } from '../../types/User';
import { AxiosResponse } from 'axios';
import BackendError from '../../exception/BackendError';
@@ -37,7 +38,6 @@ import TagStorage from '../../storage/mongodb/TagStorage';
import Tenant from '../../types/Tenant';
import Transaction from '../../types/Transaction';
import TransactionStorage from '../../storage/mongodb/TransactionStorage';
-import User from '../../types/User';
import UserStorage from '../../storage/mongodb/UserStorage';
import Utils from '../../utils/Utils';
import _ from 'lodash';
@@ -47,7 +47,7 @@ import moment from 'moment';
const MODULE_NAME = 'CpoOCPIClient';
export default class CpoOCPIClient extends OCPIClient {
- constructor(tenant: Tenant, settings: OcpiSetting, ocpiEndpoint: OCPIEndpoint) {
+ public constructor(tenant: Tenant, settings: OcpiSetting, ocpiEndpoint: OCPIEndpoint) {
super(tenant, settings, ocpiEndpoint, OCPIRole.CPO);
if (ocpiEndpoint.role !== OCPIRole.CPO) {
throw new BackendError({
@@ -58,7 +58,6 @@ export default class CpoOCPIClient extends OCPIClient {
}
public async pullTokens(partial = true): Promise<OCPIResult> {
- // Result
const result: OCPIResult = {
success: 0,
failure: 0,
@@ -67,16 +66,20 @@ export default class CpoOCPIClient extends OCPIClient {
};
// If partial (keep it global for logs)
const momentFrom = moment().utc().subtract(1, 'hours').startOf('hour');
- // EMSP Users
- const emspUsers = new Map<string, User>();
+ // Get all the EMSP Users
+ const emspUsersMap = new Map<string, User>();
+ const emspUsers = (await UserStorage.getUsers(this.tenant, { issuer: false }, Constants.DB_PARAMS_MAX_LIMIT)).result;
+ for (const emspUser of emspUsers) {
+ emspUsersMap.set(emspUser.email, emspUser);
+ }
// Perfs trace
const startTime = new Date().getTime();
// Get tokens endpoint url
let tokensUrl = this.getEndpointUrl('tokens', ServerAction.OCPI_PULL_TOKENS);
if (partial) {
- tokensUrl = `${tokensUrl}?date_from=${momentFrom.format()}&limit=100`;
+ tokensUrl = `${tokensUrl}?date_from=${momentFrom.format()}&limit=1000`;
} else {
- tokensUrl = `${tokensUrl}?limit=100`;
+ tokensUrl = `${tokensUrl}?limit=1000`;
}
let nextResult = true;
let totalNumberOfToken = 0;
@@ -116,27 +119,22 @@ export default class CpoOCPIClient extends OCPIClient {
{ tagIDs: tagIDs }, Constants.DB_PARAMS_MAX_LIMIT);
const tokens = response.data.data as OCPIToken[];
if (!Utils.isEmptyArray(tokens)) {
+ // Check and get eMSP users from Tokens
+ await this.checkAndCreateEMSPUsersFromTokens(tokens, emspUsersMap);
+ // Update the tags
await Promise.map(tokens, async (token) => {
try {
// Get eMSP user
const email = OCPIUtils.buildEmspEmailFromOCPIToken(token, this.ocpiEndpoint.countryCode, this.ocpiEndpoint.partyId);
- // Check cache
- let emspUser = emspUsers.get(email);
- if (!emspUser) {
- // Get User from DB
- emspUser = await UserStorage.getUserByEmail(this.tenant, email);
- if (emspUser) {
- emspUsers.set(email, emspUser);
- }
- }
+ const emspUser = emspUsersMap.get(email);
// Get the Tag
const emspTag = tags.result.find((tag) => tag.id === token.uid);
- await OCPIUtilsService.updateToken(this.tenant, this.ocpiEndpoint, token, emspTag, emspUser);
+ await OCPIUtilsService.updateToken(this.tenant, token, emspTag, emspUser);
result.success++;
} catch (error) {
result.failure++;
result.logs.push(
- `Failed to update Issuer '${token.issuer}' - Token ID '${token.uid}': ${error.message}`
+ `Failed to update Issuer '${token.issuer}' - Token ID '${token.uid}': ${error.message as string}`
);
}
},
@@ -541,7 +539,7 @@ export default class CpoOCPIClient extends OCPIClient {
result.failure++;
result.objectIDsInFailure.push(String(transaction.id));
result.logs.push(
- `Failed to check OCPI Transaction ID '${transaction.ocpiData.session.id}': ${error.message}`
+ `Failed to check OCPI Transaction ID '${transaction.ocpiData.session.id}': ${error.message as string}`
);
}
}
@@ -593,7 +591,7 @@ export default class CpoOCPIClient extends OCPIClient {
result.failure++;
result.objectIDsInFailure.push(String(location.id));
result.logs.push(
- `Failed to check the Location '${location.name}' with ID '${location.id}': ${error.message}`
+ `Failed to check the Location '${location.name}' with ID '${location.id}': ${error.message as string}`
);
}
}
@@ -640,7 +638,7 @@ export default class CpoOCPIClient extends OCPIClient {
result.failure++;
result.objectIDsInFailure.push(String(transaction.id));
result.logs.push(
- `${Utils.buildConnectorInfo(transaction.connectorId, transaction.id)} Failed to check CDR: ${error.message}`
+ `${Utils.buildConnectorInfo(transaction.connectorId, transaction.id)} Failed to check CDR: ${error.message as string}`
);
}
result.total++;
@@ -725,7 +723,7 @@ export default class CpoOCPIClient extends OCPIClient {
result.failure++;
result.objectIDsInFailure.push(evse.chargingStationID);
result.logs.push(
- `Update status failed on Location '${location.name}' with ID '${location.id}', Charging Station ID '${evse.evse_id}': ${error.message}`
+ `Update status failed on Location '${location.name}' with ID '${location.id}', Charging Station ID '${evse.evse_id}': ${error.message as string}`
);
}
if (result.failure > 0) {
@@ -781,6 +779,39 @@ export default class CpoOCPIClient extends OCPIClient {
return result;
}
+ private async checkAndCreateEMSPUsersFromTokens(tokens: OCPIToken[], emspUsers: Map<string, User>) {
+ if (!Utils.isEmptyArray(tokens)) {
+ for (const token of tokens) {
+ // Get eMSP user
+ const email = OCPIUtils.buildEmspEmailFromOCPIToken(token, this.ocpiEndpoint.countryCode, this.ocpiEndpoint.partyId);
+ // Check cache
+ let emspUser = emspUsers.get(email);
+ if (!emspUser) {
+ // Get User from DB
+ emspUser = await UserStorage.getUserByEmail(this.tenant, email);
+ // Create user
+ if (!emspUser) {
+ // Create User
+ emspUser = {
+ issuer: false,
+ createdOn: token.last_updated,
+ lastChangedOn: token.last_updated,
+ name: token.issuer,
+ firstName: OCPIUtils.buildOperatorName(this.ocpiEndpoint.countryCode, this.ocpiEndpoint.partyId),
+ email: OCPIUtils.buildEmspEmailFromOCPIToken(token, this.ocpiEndpoint.countryCode, this.ocpiEndpoint.partyId),
+ locale: Utils.getLocaleFromLanguage(token.language),
+ } as User;
+ // Save User
+ emspUser.id = await UserStorage.saveUser(this.tenant, emspUser);
+ await UserStorage.saveUserRole(this.tenant, emspUser.id, UserRole.BASIC);
+ await UserStorage.saveUserStatus(this.tenant, emspUser.id, UserStatus.ACTIVE);
+ }
+ emspUsers.set(email, emspUser);
+ }
+ }
+ }
+ }
+
private async getChargeBoxIDsWithNewStatusNotifications(): Promise<string[]> {
// Get last job
const lastPatchJobOn = this.ocpiEndpoint.lastPatchJobOn ? this.ocpiEndpoint.lastPatchJobOn : new Date();

MODIFY
src/migration/tasks/UpdateEmailsToLowercaseTask.ts
src/migration/tasks/UpdateEmailsToLowercaseTask.ts
@@ -32,7 +32,7 @@ export default class UpdateEmailsToLowercaseTask extends TenantMigrationTask {
}
public getVersion(): string {
- return '1.0';
+ return '1.1';
}
public getName(): string {

MODIFY
src/server/ocpi/OCPIUtils.ts
src/server/ocpi/OCPIUtils.ts
@@ -101,7 +101,7 @@ export default class OCPIUtils {
public static buildEmspEmailFromOCPIToken(token: OCPIToken, countryCode: string, partyId: string): string {
if (token?.issuer) {
- return `${token.issuer}@${partyId}.${countryCode}`;
+ return `${token.issuer}@${partyId}.${countryCode}`.toLowerCase();
}
}

MODIFY
src/server/ocpi/ocpi-services-impl/ocpi-2.1.1/OCPIUtilsService.ts
src/server/ocpi/ocpi-services-impl/ocpi-2.1.1/OCPIUtilsService.ts
@@ -651,7 +651,7 @@ export default class OCPIUtilsService {
await this.updateConnector(tenant, transaction);
}
- public static async updateToken(tenant: Tenant, ocpiEndpoint: OCPIEndpoint, token: OCPIToken, tag: Tag, emspUser: User): Promise<void> {
+ public static async updateToken(tenant: Tenant, token: OCPIToken, tag: Tag, emspUser: User): Promise<void> {
if (!OCPIUtilsService.validateToken(token)) {
throw new AppError({
module: MODULE_NAME, method: 'updateToken',
@@ -661,45 +661,29 @@ export default class OCPIUtilsService {
ocpiError: OCPIStatusCode.CODE_2001_INVALID_PARAMETER_ERROR
});
}
- if (emspUser) {
// External organization
- if (emspUser.issuer) {
+ if (!emspUser) {
throw new AppError({
module: MODULE_NAME, method: 'updateToken',
errorCode: StatusCodes.CONFLICT,
- message: 'Token already assigned to an internal user',
- actionOnUser: emspUser,
+ message: 'eMSP User is mandatory',
detailedMessages: { token },
ocpiError: OCPIStatusCode.CODE_2001_INVALID_PARAMETER_ERROR
});
}
- // Check the tag
- if (tag && tag.issuer) {
+ // External organization
+ if (emspUser.issuer) {
throw new AppError({
- module: MODULE_NAME, method: 'checkExistingTag',
+ module: MODULE_NAME, method: 'updateToken',
errorCode: StatusCodes.CONFLICT,
- message: 'Token already exists in the current organization',
- detailedMessages: token,
+ message: 'Token already assigned to an internal user',
+ actionOnUser: emspUser,
+ detailedMessages: { token },
ocpiError: OCPIStatusCode.CODE_2001_INVALID_PARAMETER_ERROR
});
}
- const tagToSave = {
- id: token.uid,
- issuer: false,
- userID: emspUser.id,
- active: token.valid === true ? true : false,
- description: token.visual_number,
- lastChangedOn: token.last_updated,
- ocpiToken: token
- };
- // Save Tag
- if (!tag || JSON.stringify(tagToSave.ocpiToken) !== JSON.stringify(tag.ocpiToken)) {
- await TagStorage.saveTag(tenant, tagToSave);
- }
- } else {
- // Unknown User
- // Check the Tag
- if (tag && tag.issuer) {
+ // Check the tag
+ if (tag?.issuer) {
throw new AppError({
module: MODULE_NAME, method: 'checkExistingTag',
errorCode: StatusCodes.CONFLICT,
@@ -708,26 +692,12 @@ export default class OCPIUtilsService {
ocpiError: OCPIStatusCode.CODE_2001_INVALID_PARAMETER_ERROR
});
}
- // Create User
- emspUser = {
- issuer: false,
- createdOn: token.last_updated,
- lastChangedOn: token.last_updated,
- name: token.issuer,
- firstName: OCPIUtils.buildOperatorName(ocpiEndpoint.countryCode, ocpiEndpoint.partyId),
- email: OCPIUtils.buildEmspEmailFromOCPIToken(token, ocpiEndpoint.countryCode, ocpiEndpoint.partyId),
- locale: Utils.getLocaleFromLanguage(token.language),
- } as User;
- // Save User
- emspUser.id = await UserStorage.saveUser(tenant, emspUser);
- await UserStorage.saveUserRole(tenant, emspUser.id, UserRole.BASIC);
- await UserStorage.saveUserStatus(tenant, emspUser.id, UserStatus.ACTIVE);
const tagToSave = {
id: token.uid,
issuer: false,
userID: emspUser.id,
active: token.valid === true ? true : false,
- description: 'OCPI token',
+ description: token.visual_number,
lastChangedOn: token.last_updated,
ocpiToken: token
};
@@ -736,7 +706,6 @@ export default class OCPIUtilsService {
await TagStorage.saveTag(tenant, tagToSave);
}
}
- }
public static async convertConnector2OCPIConnector(tenant: Tenant, chargingStation: ChargingStation, connector: Connector, countryId: string, partyId: string): Promise<OCPIConnector> {
let type: OCPIConnectorType, format: OCPIConnectorFormat;

MODIFY
src/server/ocpi/ocpi-services-impl/ocpi-2.1.1/cpo/CPOTokensEndpoint.ts
src/server/ocpi/ocpi-services-impl/ocpi-2.1.1/cpo/CPOTokensEndpoint.ts
@@ -142,7 +142,7 @@ export default class CPOTokensEndpoint extends AbstractEndpoint {
detailedMessages: { operator, token, tag }
});
}
- await OCPIUtilsService.updateToken(tenant, ocpiEndpoint, token, tag, tag.user);
+ await OCPIUtilsService.updateToken(tenant, token, tag, tag.user);
return OCPIUtils.success();
}

MODIFY
src/server/rest/v1/service/OCPIEndpointService.ts
src/server/rest/v1/service/OCPIEndpointService.ts
@@ -25,7 +25,7 @@ import UtilsService from './UtilsService';
const MODULE_NAME = 'OCPIEndpointService';
export default class OCPIEndpointService {
- static async handleDeleteOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleDeleteOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.DELETE, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handleDeleteOcpiEndpoint');
@@ -58,7 +58,7 @@ export default class OCPIEndpointService {
next();
}
- static async handleGetOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleGetOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.READ, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handleGetOcpiEndpoint');
@@ -86,7 +86,7 @@ export default class OCPIEndpointService {
next();
}
- static async handleGetOcpiEndpoints(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleGetOcpiEndpoints(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.LIST, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handleGetOcpiEndpoints');
@@ -126,7 +126,7 @@ export default class OCPIEndpointService {
next();
}
- static async handleCreateOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleCreateOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.CREATE, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handleCreateOcpiEndpoint');
@@ -159,7 +159,7 @@ export default class OCPIEndpointService {
next();
}
- static async handleUpdateOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleUpdateOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.UPDATE, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handleUpdateOcpiEndpoint');
@@ -195,7 +195,7 @@ export default class OCPIEndpointService {
next();
}
- static async handlePingOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handlePingOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.READ, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handlePingOcpiEndpoint');
@@ -235,7 +235,7 @@ export default class OCPIEndpointService {
next();
}
- static async handlePullLocationsEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handlePullLocationsEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.READ, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handlePullLocationsEndpoint');
@@ -286,7 +286,7 @@ export default class OCPIEndpointService {
next();
}
- static async handlePullSessionsEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handlePullSessionsEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.READ, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handlePullSessionsEndpoint');
@@ -336,7 +336,7 @@ export default class OCPIEndpointService {
next();
}
- static async handlePullTokensEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handlePullTokensEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.READ, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handlePullTokensEndpoint');
@@ -386,7 +386,7 @@ export default class OCPIEndpointService {
next();
}
- static async handlePullCdrsEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handlePullCdrsEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.READ, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handlePullCdrsEndpoint');
@@ -436,7 +436,7 @@ export default class OCPIEndpointService {
next();
}
- static async handleCheckCdrsEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleCheckCdrsEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.READ, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handleCheckCdrsEndpoint');
@@ -486,7 +486,7 @@ export default class OCPIEndpointService {
next();
}
- static async handleCheckSessionsEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleCheckSessionsEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.READ, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handleCheckSessionsEndpoint');
@@ -536,7 +536,7 @@ export default class OCPIEndpointService {
next();
}
- static async handleCheckLocationsEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleCheckLocationsEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.READ, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handleCheckLocationsEndpoint');
@@ -586,7 +586,7 @@ export default class OCPIEndpointService {
next();
}
- static async handlePushEVSEStatusesOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handlePushEVSEStatusesOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.READ, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handlePushEVSEStatusesOcpiEndpoint');
@@ -636,7 +636,7 @@ export default class OCPIEndpointService {
next();
}
- static async handlePushTokensOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handlePushTokensOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.READ, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handlePushTokensOcpiEndpoint');
@@ -687,7 +687,7 @@ export default class OCPIEndpointService {
next();
}
- static async handleUnregisterOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleUnregisterOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.READ, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handleUnregisterOcpiEndpoint');
@@ -740,7 +740,7 @@ export default class OCPIEndpointService {
next();
}
- static async handleRegisterOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleRegisterOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.UPDATE, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handleRegisterOcpiEndpoint');
@@ -793,7 +793,7 @@ export default class OCPIEndpointService {
next();
}
- static async handleGenerateLocalTokenOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleGenerateLocalTokenOcpiEndpoint(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.OCPI,
Action.UPDATE, Entity.OCPI_ENDPOINT, MODULE_NAME, 'handleGenerateLocalTokenOcpiEndpoint');

Fixed email in lower case in OCPI