1- import { BadRequestException , Injectable , Logger , OnApplicationBootstrap } from '@nestjs/common' ;
2- import { parse } from 'yaml' ;
3- import { existsSync , readFileSync , readdirSync , writeFileSync } from 'fs' ;
4- import { ConfigObjectSchemaDTO } from './_dto/config.dto' ;
5- import { diff } from 'radash' ;
6- import { AdditionalFieldsPart } from '../_schemas/_parts/additionalFields.part.schema' ;
1+ import { BadRequestException , Injectable , Logger , OnApplicationBootstrap } from '@nestjs/common' ;
2+ import { parse } from 'yaml' ;
3+ import { existsSync , readFileSync , readdirSync , writeFileSync } from 'fs' ;
4+ import { ConfigObjectSchemaDTO } from './_dto/config.dto' ;
5+ import { diff } from 'radash' ;
6+ import { AdditionalFieldsPart } from '../_schemas/_parts/additionalFields.part.schema' ;
77import Ajv from 'ajv' ;
88import addFormats from 'ajv-formats' ;
99import validSchema from './_config/validSchema' ;
1010import ajvErrors from 'ajv-errors' ;
11- import { ValidationConfigException , ValidationSchemaException } from '~/_common/errors/ValidationException' ;
12- import { additionalFieldsPartDto } from '../_dto/_parts/additionalFields.dto' ;
11+ import { ValidationConfigException , ValidationSchemaException } from '~/_common/errors/ValidationException' ;
12+ import { additionalFieldsPartDto } from '../_dto/_parts/additionalFields.dto' ;
1313
1414/**
1515 * Service responsible for validating identities.
1616 */
1717@Injectable ( )
1818export class IdentitiesValidationService implements OnApplicationBootstrap {
19- private ajv : Ajv = new Ajv ( { allErrors : true } ) ;
19+ private ajv : Ajv = new Ajv ( { allErrors : true } ) ;
2020 private validateSchema ;
2121 private logger : Logger ;
2222
2323 public constructor ( ) {
2424 addFormats ( this . ajv ) ;
2525 ajvErrors ( this . ajv ) ;
26- this . ajv . addFormat ( 'number' , / ^ \d * $ / ) ;
26+ this . ajv . addFormat ( 'number' , / ^ \d * $ / ) ;
2727 this . validateSchema = this . ajv . compile ( validSchema ) ;
2828 this . logger = new Logger ( IdentitiesValidationService . name ) ;
2929 }
@@ -93,26 +93,26 @@ export class IdentitiesValidationService implements OnApplicationBootstrap {
9393 * check objectclasses and add missing keys
9494 * @param data
9595 */
96- public async checkAndCreateObjectClasses ( data ) {
96+ public async checkAndCreateObjectClasses ( data ) {
9797 const objectClasses = data . objectClasses || [ ] ;
9898 const attributes = data . attributes || { } ;
9999 const attributesKeys = Object . keys ( attributes ) ;
100- for ( const objectclass of objectClasses ) {
101- if ( ! attributesKeys . includes ( objectclass ) ) {
102- this . logger . log ( objectclass + " attribute not found creating" ) ;
103- await this . createAttributes ( objectclass , data ) ;
100+ for ( const objectclass of objectClasses ) {
101+ if ( ! attributesKeys . includes ( objectclass ) ) {
102+ this . logger . log ( objectclass + " attribute not found creating" ) ;
103+ await this . createAttributes ( objectclass , data ) ;
104104 }
105105 }
106106 }
107- private async createAttributes ( key :string , data :any ) {
107+ private async createAttributes ( key : string , data : any ) {
108108
109109 // Validate the key to prevent prototype pollution
110110 if ( key === '__proto__' || key === 'constructor' || key === 'prototype' ) {
111111 this . logger . error ( 'Invalid key: ' + key ) ;
112112 throw new BadRequestException ( 'Invalid key: ' + key ) ;
113113 }
114114 const path = this . resolveConfigPath ( key ) ;
115- if ( path === null ) {
115+ if ( path === null ) {
116116 this . logger . error ( 'schema for ' + key + ' does not exist' ) ;
117117 throw new BadRequestException ( 'schema for ' + key + ' does not exist' ) ;
118118 }
@@ -148,7 +148,7 @@ export class IdentitiesValidationService implements OnApplicationBootstrap {
148148 public async transformAttribute ( key : string , attribute : any , data : any ) {
149149
150150 const path = this . resolveConfigPath ( key ) ;
151- if ( path === null ) {
151+ if ( path === null ) {
152152 this . logger . error ( 'schema for ' + key + ' does not exist' ) ;
153153 throw new BadRequestException ( 'schema for ' + key + ' does not exist' ) ;
154154 }
@@ -160,42 +160,42 @@ export class IdentitiesValidationService implements OnApplicationBootstrap {
160160 if ( typeof data [ key ] [ index ] === 'undefined' || data [ key ] [ index ] === null ) {
161161 data [ key ] [ index ] = [ ] ;
162162 }
163- if ( ! ( data [ key ] [ index ] instanceof Array ) ) {
164- data [ key ] [ index ] = [ data [ key ] [ index ] ] ;
163+ if ( ! ( data [ key ] [ index ] instanceof Array ) ) {
164+ data [ key ] [ index ] = [ data [ key ] [ index ] ] ;
165165 }
166166 if ( typeof def [ 'items' ] !== 'undefined' ) {
167- //test si toutes les valeurs sont du bon type
168- for ( const elems in data [ key ] [ index ] ) {
169- if ( typeof data [ key ] [ index ] [ elems ] !== def [ 'items' ] [ 'type' ] ) {
170- switch ( def [ 'items' ] [ 'type' ] ) {
171- case 'string' :
172- data [ key ] [ index ] [ elems ] = String ( data [ key ] [ index ] [ elems ] ) ;
173- break ;
174- case 'number' :
175- data [ key ] [ index ] [ elems ] = await this . transformNumber ( data [ key ] [ index ] [ elems ] )
176- break ;
177- }
167+ //test si toutes les valeurs sont du bon type
168+ for ( const elems in data [ key ] [ index ] ) {
169+ if ( typeof data [ key ] [ index ] [ elems ] !== def [ 'items' ] [ 'type' ] ) {
170+ switch ( def [ 'items' ] [ 'type' ] ) {
171+ case 'string' :
172+ data [ key ] [ index ] [ elems ] = String ( data [ key ] [ index ] [ elems ] ) ;
173+ break ;
174+ case 'number' :
175+ data [ key ] [ index ] [ elems ] = await this . transformNumber ( data [ key ] [ index ] [ elems ] )
176+ break ;
178177 }
179178 }
179+ }
180180 }
181181 break ;
182182 case 'number' :
183183 if ( typeof data [ key ] [ index ] === 'undefined' || data [ key ] [ index ] === null ) {
184184 data [ key ] [ index ] = 0 ;
185185 }
186- if ( typeof data [ key ] [ index ] !== 'number' ) {
186+ if ( typeof data [ key ] [ index ] !== 'number' ) {
187187 //on ne convertit pas si la chaine est vide
188- if ( typeof data [ key ] [ index ] === 'string' && data [ key ] [ index ] !== "" ) {
189- data [ key ] [ index ] = await this . transformNumber ( data [ key ] [ index ] )
188+ if ( typeof data [ key ] [ index ] === 'string' && data [ key ] [ index ] !== "" ) {
189+ data [ key ] [ index ] = await this . transformNumber ( data [ key ] [ index ] )
190190 }
191191 }
192192 break ;
193193 case 'string' :
194194 if ( typeof data [ key ] [ index ] === 'undefined' || data [ key ] [ index ] === null ) {
195195 data [ key ] [ index ] = "" ;
196196 }
197- if ( typeof data [ key ] [ index ] !== 'string' ) {
198- data [ key ] [ index ] = String ( data [ key ] [ index ] ) ;
197+ if ( typeof data [ key ] [ index ] !== 'string' ) {
198+ data [ key ] [ index ] = String ( data [ key ] [ index ] ) ;
199199 }
200200 break ;
201201 }
@@ -207,12 +207,12 @@ export class IdentitiesValidationService implements OnApplicationBootstrap {
207207 * @param value
208208 * @private
209209 */
210- private async transformNumber ( value ) {
211- if ( typeof value === 'string' ) {
212- const tr = parseFloat ( value )
213- if ( ! isNaN ( tr ) ) {
210+ private async transformNumber ( value ) {
211+ if ( typeof value === 'string' ) {
212+ const tr = parseFloat ( value )
213+ if ( ! isNaN ( tr ) ) {
214214 return tr
215- } else {
215+ } else {
216216 return 0
217217 }
218218 }
@@ -263,15 +263,16 @@ export class IdentitiesValidationService implements OnApplicationBootstrap {
263263 }
264264
265265 // Check for invalid schema
266+ this . logger . verbose ( `Validating schema ${ key } .yml` ) ;
266267 const schema : ConfigObjectSchemaDTO = parse ( readFileSync ( path , 'utf8' ) ) ;
267268 if ( ! this . validateSchema ( schema ) ) {
268269 validations [ 'message' ] = `Schema ${ key } .yml invalide: ${ this . ajv . errorsText ( this . validateSchema . errors ) } ` ;
269270 throw new ValidationConfigException ( validations ) ;
270271 }
271272 //verification des required, il faut que l'entree soit presente dans les proprietes
272273 if ( schema . hasOwnProperty ( 'required' ) ) {
273- for ( const required of schema [ 'required' ] ) {
274- if ( ! schema [ 'properties' ] . hasOwnProperty ( required ) ) {
274+ for ( const required of schema [ 'required' ] ) {
275+ if ( ! schema [ 'properties' ] . hasOwnProperty ( required ) ) {
275276 validations [ 'message' ] = `Schema ${ key } .yml invalide : required : ${ required } without property` ;
276277 throw new ValidationConfigException ( validations ) ;
277278 }
@@ -290,9 +291,9 @@ export class IdentitiesValidationService implements OnApplicationBootstrap {
290291 }
291292
292293 if ( reject ) {
293- throw new ValidationSchemaException ( { validations} ) ;
294+ throw new ValidationSchemaException ( { validations } ) ;
294295 }
295- return Promise . resolve ( { message : 'Validation succeeded' } ) ;
296+ return Promise . resolve ( { message : 'Validation succeeded' } ) ;
296297 }
297298
298299 /**
@@ -334,23 +335,23 @@ export class IdentitiesValidationService implements OnApplicationBootstrap {
334335 this . logger . debug ( `Additionalfields object validation: ${ JSON . stringify ( data [ key ] ) } ` ) ;
335336 //limitation de la taille du data pour le pb de deny of service de ajv
336337 //voir (https://ajv.js.org/security.html)
337- if ( Object . keys ( data [ key ] ) . length > 500 ) {
338+ if ( Object . keys ( data [ key ] ) . length > 500 ) {
338339 this . logger . error ( 'Request too large' ) ;
339340 throw new BadRequestException ( 'Request too large' ) ;
340341 }
341- const ok = await this . ajv . validate ( schema , data [ key ] ) ;
342+ const ok = await this . ajv . validate ( schema , data [ key ] ) ;
342343 if ( ok === false ) {
343344 const retErrors = { } ;
344345 for ( const err of this . ajv . errors ) {
345- retErrors [ err [ 'instancePath' ] . substring ( 1 ) ] = err [ 'instancePath' ] . substring ( 1 ) + ' ' + err [ 'message' ]
346+ retErrors [ err [ 'instancePath' ] . substring ( 1 ) ] = err [ 'instancePath' ] . substring ( 1 ) + ' ' + err [ 'message' ]
346347 }
347- return ( retErrors )
348+ return ( retErrors )
348349 }
349350 return null
350351 }
351352
352353 public async findAll ( ) : Promise < any > {
353- this . logger . debug ( [ 'findAll' , JSON . stringify ( Object . values ( { ...arguments } ) ) ] . join ( ' ' ) ) ;
354+ this . logger . debug ( [ 'findAll' , JSON . stringify ( Object . values ( { ...arguments } ) ) ] . join ( ' ' ) ) ;
354355 const hardConfigPath = './src/management/identities/validations/_config' ;
355356 const dynamicConfigPath = './configs/identities/validations' ;
356357 // Retrieve files from each directory and tag them with their source
@@ -399,7 +400,7 @@ export class IdentitiesValidationService implements OnApplicationBootstrap {
399400 const filePath = `${ fileObj . path } /${ fileObj . file } ` ;
400401 const data = parse ( readFileSync ( filePath , 'utf-8' ) ) ;
401402 const key = fileObj . file . replace ( '.yml' , '' ) ;
402- result . push ( { [ key ] : data , source : fileObj . source , name : key } ) ;
403+ result . push ( { [ key ] : data , source : fileObj . source , name : key } ) ;
403404 }
404405 return [ result , files . length ] ;
405406 }
@@ -411,13 +412,13 @@ export class IdentitiesValidationService implements OnApplicationBootstrap {
411412 filePath = './validation/inetorgperson.json' ;
412413 if ( ! existsSync ( filePath ) ) {
413414 const message = `File not found /validation/inetorgperson.json` ;
414- throw new ValidationConfigException ( { message} ) ;
415+ throw new ValidationConfigException ( { message } ) ;
415416 }
416417 } else {
417418 filePath = this . resolveConfigPath ( schema ) ;
418419 if ( ! existsSync ( filePath ) ) {
419420 const message = `File not found: ${ filePath } ` ;
420- throw new ValidationConfigException ( { message} ) ;
421+ throw new ValidationConfigException ( { message } ) ;
421422 }
422423 }
423424 return parse ( readFileSync ( filePath , 'utf-8' ) ) ;
0 commit comments