Added setting create schema
ADD
src/assets/schemas/setting/setting.json
+{
+ "$id": "setting",
+ "definitions": {
+ "id": {
+ "$ref": "common#/definitions/id"
+ },
+ "identifier": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "sensitiveData": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "sanitize": "mongo"
+ }
+ }
+}

ADD
src/assets/server/rest/v1/schemas/setting/setting-create.json
+{
+ "$id": "setting-create",
+ "title": "Setting creation Request",
+ "type": "object",
+ "properties": {
+ "identifier": {
+ "$ref": "setting#/definitions/identifier"
+ },
+ "sensitiveData": {
+ "$ref": "setting#/definitions/sensitiveData"
+ },
+ "content": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "links": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "name": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "description": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "role": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "url": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ }
+ },
+ "sac": {
+ "type": "object",
+ "properties": {
+ "mainUrl": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "timezone": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "ocpi": {
+ "type": "object",
+ "properties": {
+ "businessDetails": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "website": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "logo": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "thumbnail": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "category": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "type": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "width": {
+ "type": "number",
+ "sanitize": "mongo"
+ },
+ "height": {
+ "type": "number",
+ "sanitize": "mongo"
+ }
+ }
+ }
+ }
+ },
+ "cpo": {
+ "type": "object",
+ "properties": {
+ "countryCode": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "partyID": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "emsp": {
+ "type": "object",
+ "properties": {
+ "countryCode": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "partyID": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "currency": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "oicp": {
+ "type": "object",
+ "properties": {
+ "businessDetails": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "website": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "logo": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "thumbnail": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "category": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "type": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "width": {
+ "type": "number",
+ "sanitize": "mongo"
+ },
+ "height": {
+ "type": "number",
+ "sanitize": "mongo"
+ }
+ }
+ }
+ }
+ },
+ "cpo": {
+ "type": "object",
+ "properties": {
+ "countryCode": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "partyID": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "key": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "cert": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "emsp": {
+ "type": "object",
+ "properties": {
+ "countryCode": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "partyID": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "key": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "cert": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "currency": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "concur": {
+ "type": "object",
+ "properties": {
+ "authenticationUrl": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "apiUrl": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "appUrl": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "clientId": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "clientSecret": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "paymentTypeId": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "expenseTypeCode": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "policyId": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "reportName": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "convergentCharging": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "chargeableItemName": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "user": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "password": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "simple": {
+ "type": "object",
+ "properties": {
+ "price": {
+ "type": "number",
+ "sanitize": "mongo"
+ },
+ "currency": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "billing": {
+ "type": "object",
+ "properties": {
+ "isTransactionBillingActivated": {
+ "type": "boolean",
+ "sanitize": "mongo"
+ },
+ "immediateBillingAllowed": {
+ "type": "boolean",
+ "sanitize": "mongo"
+ },
+ "periodicBillingAllowed": {
+ "type": "boolean",
+ "sanitize": "mongo"
+ },
+ "taxID": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "stripe": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "secretKey": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "publicKey": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "sapSmartCharging": {
+ "type": "object",
+ "properties": {
+ "optimizerUrl": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "user": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "password": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "stickyLimitation": {
+ "type": "boolean",
+ "sanitize": "mongo"
+ },
+ "limitBufferDC": {
+ "type": "number",
+ "sanitize": "mongo"
+ },
+ "limitBufferAC": {
+ "type": "number",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "asset": {
+ "type": "object",
+ "properties": {
+ "connections": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "name": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "description": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "url": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "type": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "refreshIntervalMins": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "schneiderConnection": {
+ "type": "object",
+ "properties": {
+ "user": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "password": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "greenComConnection": {
+ "type": "object",
+ "properties": {
+ "clientId": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "clientSecret": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "iothinkConnection": {
+ "type": "object",
+ "properties": {
+ "user": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "password": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "witConnection": {
+ "type": "object",
+ "properties": {
+ "authenticationUrl": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "clientId": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "clientSecret": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "user": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "password": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "lacroix": {
+ "type": "object",
+ "properties": {
+ "user": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "password": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "carConnector": {
+ "type": "object",
+ "properties": {
+ "connections": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "name": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "description": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "type": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "mercedesConnection": {
+ "type": "object",
+ "properties": {
+ "authenticationUrl": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "apiUrl": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "clientId": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "clientSecret": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "tronityConnection": {
+ "type": "object",
+ "properties": {
+ "apiUrl": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "clientId": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "clientSecret": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "crypto": {
+ "type": "object",
+ "properties": {
+ "key": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "keyProperties": {
+ "type": "object",
+ "properties": {
+ "blockCypher": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "blockSize": {
+ "type": "number",
+ "sanitize": "mongo"
+ },
+ "operationMode": {
+ "type": "number",
+ "sanitize": "mongo"
+ }
+ }
+ },
+ "formerKey": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "formerKeyProperties": {
+ "type": "object",
+ "properties": {
+ "blockCypher": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "blockSize": {
+ "type": "number",
+ "sanitize": "mongo"
+ },
+ "operationMode": {
+ "type": "number",
+ "sanitize": "mongo"
+ }
+ }
+ }
+ }
+ },
+ "user": {
+ "type": "object",
+ "properties": {
+ "autoActivateAccountAfterValidation": {
+ "type": "boolean",
+ "sanitize": "mongo"
+ }
+ }
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "oneOf": [
+ { "required": [] },
+ { "required": ["sac"] },
+ { "required": ["ocpi"] },
+ { "required": ["oicp"] },
+ { "required": ["concur"] },
+ { "required": ["convergentCharging"] },
+ { "required": ["simple"] },
+ { "required": ["billing"] },
+ { "required": ["stripe"] },
+ { "required": ["smartCharging"] },
+ { "required": ["asset"] },
+ { "required": ["carConnector"] },
+ { "required": ["crypto"] },
+ { "required": ["user"] }
+ ]
+ }
+ },
+ "required": [
+ "identifier",
+ "content"
+ ]
+}

MODIFY
src/server/rest/v1/service/SettingService.ts
src/server/rest/v1/service/SettingService.ts
@@ -11,6 +11,7 @@ import Logging from '../../../../utils/Logging';
import { ServerAction } from '../../../../types/Server';
import SettingSecurity from './security/SettingSecurity';
import SettingStorage from '../../../../storage/mongodb/SettingStorage';
+import SettingValidator from '../validator/SettingValidator';
import { StatusCodes } from 'http-status-codes';
import { TechnicalSettings } from '../../../../types/Setting';
import Utils from '../../../../utils/Utils';
@@ -154,7 +155,7 @@ export default class SettingService {
});
}
// Filter
- const filteredRequest = SettingSecurity.filterSettingCreateRequest(req.body);
+ const filteredRequest = SettingValidator.getInstance().validateSettingCreateReq(req.body);
// Process the sensitive data if any
await Cypher.encryptSensitiveDataInJSON(req.tenant, filteredRequest);
// Update timestamp

ADD
src/server/rest/v1/validator/SettingValidator.ts
+import Schema from '../../../../types/validator/Schema';
+import SchemaValidator from '../../../../validator/SchemaValidator';
+import { Setting } from '../../../../types/Setting';
+import fs from 'fs';
+import global from '../../../../types/GlobalType';
+
+export default class SettingValidator extends SchemaValidator {
+ private static instance: SettingValidator | null = null;
+ private settingCreate: Schema;
+
+ private constructor() {
+ super('SettingValidator');
+ this.settingCreate = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/setting/setting-create.json`, 'utf8'));
+ }
+
+ public static getInstance(): SettingValidator {
+ if (!SettingValidator.instance) {
+ SettingValidator.instance = new SettingValidator();
+ }
+ return SettingValidator.instance;
+ }
+
+ public validateSettingCreateReq(data: Record<string, unknown>): Setting {
+ return this.validate(this.settingCreate, data);
+ }
+}

MODIFY
src/validator/SchemaValidator.ts
src/validator/SchemaValidator.ts
@@ -29,6 +29,7 @@ export default class SchemaValidator {
private static assetSchema: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/schemas/asset/asset.json`, 'utf8'));
private static companySchema: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/schemas/company/company.json`, 'utf8'));
private static ocpiEndpointSchema: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/schemas/ocpi/ocpi-endpoint.json`, 'utf8'));
+ private static settingSchema: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/schemas/setting/setting.json`, 'utf8'));
private readonly ajv: Ajv;
constructor(readonly moduleName: string,
@@ -63,6 +64,7 @@ export default class SchemaValidator {
this.ajv.addSchema(SchemaValidator.assetSchema);
this.ajv.addSchema(SchemaValidator.companySchema);
this.ajv.addSchema(SchemaValidator.ocpiEndpointSchema);
+ this.ajv.addSchema(SchemaValidator.settingSchema);
}
protected validate(schema: Schema, data: Record<string, unknown>): any {

Added setting create schema