Skip to content

Commit 21d7313

Browse files
Refactor identity validation service and controller
1 parent 6eb85d9 commit 21d7313

File tree

4 files changed

+56
-63
lines changed

4 files changed

+56
-63
lines changed

src/management/identities/_schemas/_parts/additionalFields.part.schema.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ export class AdditionalFieldsPart {
77
objectClasses: string[];
88

99
@Prop({ type: Object, required: true })
10-
attributes: { [key: string]: MixedValue };
10+
attributes: Record<string, MixedValue>;
11+
12+
@Prop({ type: Object, required: false })
13+
validations: Record<string, string>;
1114
}
1215

1316
export const AdditionalFieldsPartSchema = SchemaFactory.createForClass(AdditionalFieldsPart);

src/management/identities/identities.controller.ts

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { IdentitiesDto, IdentitiesCreateDto, IdentitiesUpdateDto } from './_dto/
1414
import { IdentitiesService } from './identities.service';
1515
import { AbstractController } from '~/_common/abstracts/abstract.controller';
1616
import { ApiParam, ApiTags } from '@nestjs/swagger';
17-
import { Types } from 'mongoose';
1817
import { ApiCreateDecorator } from '~/_common/decorators/api-create.decorator';
1918
import { ApiDeletedResponseDecorator } from '~/_common/decorators/api-deleted-response.decorator';
2019
import { ApiPaginatedDecorator } from '~/_common/decorators/api-paginated.decorator';
@@ -28,10 +27,11 @@ import { FilterOptions, FilterSchema, SearchFilterOptions, SearchFilterSchema }
2827
import { IdentitiesValidationService } from './validations/identities.validation.service';
2928
import { MixedValue } from '~/_common/types/mixed-value.type';
3029
import { Identities } from './_schemas/identities.schema';
31-
import { Document } from 'mongoose';
32-
import { ValidationConfigException, ValidationSchemaException } from '~/_common/errors/ValidationException';
30+
import { Types, Document } from 'mongoose';
3331
import { IdentityState } from './_enums/states.enum';
32+
// import { IdentitiesValidationFilter } from '~/_common/filters/identities-validation.filter';
3433

34+
// @UseFilters(new IdentitiesValidationFilter())
3535
@ApiTags('management')
3636
@Controller('identities')
3737
export class IdentitiesController extends AbstractController {
@@ -64,29 +64,21 @@ export class IdentitiesController extends AbstractController {
6464
any
6565
>
6666
> {
67-
try {
68-
let statusCode = HttpStatus.CREATED;
69-
let message = null;
70-
const data = await this._service.create<Identities>(body);
71-
if (data.state === IdentityState.TO_COMPLETE) {
72-
statusCode = HttpStatus.ACCEPTED;
73-
message = 'Identitée créée avec succès, mais des champs additionnels sont manquants ou invalides.';
74-
}
75-
return res.status(statusCode).json({
76-
statusCode,
77-
data,
78-
message,
79-
});
80-
} catch (error) {
81-
let validations = error.validations;
82-
if (error instanceof ValidationSchemaException || error instanceof ValidationConfigException)
83-
validations = error.getResponse().response;
84-
return res.status(HttpStatus.BAD_REQUEST).json({
85-
statusCode: HttpStatus.BAD_REQUEST,
86-
message: error.message,
87-
validations: validations,
88-
});
67+
let statusCode = HttpStatus.CREATED;
68+
let message = null;
69+
const data = await this._service.create<Identities>(body);
70+
// If the state is TO_COMPLETE, the identity is created but additional fields are missing or invalid
71+
// Else the state is TO_VALIDATE, we return a 201 status code
72+
if ((data as Identities).state === IdentityState.TO_COMPLETE) {
73+
statusCode = HttpStatus.ACCEPTED;
74+
message = 'Identitée créée avec succès, mais des champs additionnels sont manquants ou invalides.';
8975
}
76+
77+
return res.status(statusCode).json({
78+
statusCode,
79+
data,
80+
message,
81+
});
9082
}
9183

9284
@Get()
Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BadRequestException, Logger, Module } from '@nestjs/common';
1+
import { HttpException, Logger, Module } from '@nestjs/common';
22
import { MongooseModule } from '@nestjs/mongoose';
33
import { IdentitiesSchema, Identities } from './_schemas/identities.schema';
44
import { IdentitiesService } from './identities.service';
@@ -17,55 +17,54 @@ import { ValidationConfigException, ValidationSchemaException } from '~/_common/
1717
inject: [IdentitiesValidationService],
1818
useFactory: (validationService: IdentitiesValidationService) => {
1919
const schema = IdentitiesSchema;
20-
// Pre validation hook
21-
// This hook is used to validate the additionalFields
22-
// If the validation fails and the state is TO_CREATE, the state is set to TO_COMPLETE
23-
// Else the error is thrown
20+
2421
schema.pre('validate', async function (next) {
25-
const commonLogMessage = `additionalFields error for ${this.inetOrgPerson.cn} `;
22+
const logPrefix = `Validation [${this.inetOrgPerson.cn}]:`;
2623
try {
27-
Logger.log(`additionalFields validation start for ${this.inetOrgPerson.cn} `);
28-
24+
Logger.log(`${logPrefix} Starting additionalFields validation.`);
2925
await validationService.validate(this.additionalFields);
30-
31-
Logger.log(`additionalFields validation end for ${this.inetOrgPerson.cn} `);
26+
Logger.log(`${logPrefix} AdditionalFields validation successful.`);
3227
} catch (error) {
33-
// If the error is a ValidationConfigException, we throw it
34-
if (error instanceof ValidationConfigException) {
35-
Logger.error(commonLogMessage, error.getResponse());
36-
throw new ValidationConfigException(error);
37-
}
38-
39-
// If the error is a ValidationSchemaException and the state is TO_CREATE, we set it to TO_COMPLETE
40-
// Else we throw it
41-
if (error instanceof ValidationSchemaException) {
42-
Logger.error(commonLogMessage, error.getResponse());
43-
if (this.state === IdentityState.TO_CREATE) {
44-
Logger.warn(commonLogMessage, 'Setting state to TO_COMPLETE');
45-
this.state = IdentityState.TO_COMPLETE;
46-
} else throw new ValidationSchemaException(error);
47-
} else {
48-
Logger.error(commonLogMessage, error);
49-
throw new Error(error);
50-
}
28+
handleValidationError(error, this, logPrefix);
5129
}
5230
next();
5331
});
5432

55-
// Pre save hook
56-
// This hook is used to set the state to TO_SYNC if the state is TO_CREATE
5733
schema.pre('save', async function (next) {
58-
if (this.state === IdentityState.TO_CREATE) this.state = IdentityState.TO_VALIDATE;
34+
if (this.state === IdentityState.TO_CREATE) {
35+
this.state = IdentityState.TO_VALIDATE;
36+
}
5937
next();
6038
});
6139

6240
return schema;
6341
},
64-
//TODO: Si le schema est save, pousser dans la queue de sync
6542
},
6643
]),
6744
],
6845
providers: [IdentitiesService, IdentitiesValidationService],
6946
controllers: [IdentitiesController],
7047
})
7148
export class IdentitiesModule {}
49+
50+
function handleValidationError(error: Error | HttpException, identity: Identities, logPrefix: string) {
51+
if (error instanceof ValidationConfigException) {
52+
Logger.error(`${logPrefix} Validation config error. ${JSON.stringify(error.getValidations())}`);
53+
throw new ValidationConfigException(error.getPayload());
54+
}
55+
56+
if (error instanceof ValidationSchemaException) {
57+
Logger.warn(`${logPrefix} Validation schema error. ${JSON.stringify(error.getValidations())}`);
58+
if (identity.state === IdentityState.TO_CREATE) {
59+
Logger.warn(`${logPrefix} State set to TO_COMPLETE.`);
60+
identity.state = IdentityState.TO_COMPLETE;
61+
identity.additionalFields.validations = error.getValidations();
62+
} else {
63+
Logger.error(`${logPrefix} Validation schema error. ${JSON.stringify(error.getValidations())}`);
64+
throw new ValidationSchemaException(error.getPayload());
65+
}
66+
} else {
67+
Logger.error(`${logPrefix} Unhandled error: ${error.message}`);
68+
throw error; // Rethrow the original error if it's not one of the handled types.
69+
}
70+
}

src/management/identities/validations/identities.validation.service.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { BadRequestException, Injectable, Logger } from '@nestjs/common';
1+
import { Injectable, Logger } from '@nestjs/common';
22
import { parse } from 'yaml';
33
import { existsSync, readFileSync } from 'fs';
44
import { ConfigObjectSchemaDTO } from './_dto/config.dto';
5-
import * as yup from 'yup';
6-
import { construct, diff } from 'radash';
5+
import { diff } from 'radash';
76
import { AdditionalFieldsPart } from '../_schemas/_parts/additionalFields.part.schema';
87
import Ajv from 'ajv';
98
import { buildYup } from 'schema-to-yup';
@@ -70,7 +69,7 @@ export class IdentitiesValidationService {
7069
}
7170

7271
if (reject) {
73-
throw new ValidationConfigException(validations);
72+
throw new ValidationConfigException({ validations });
7473
}
7574

7675
// Validate each attribute
@@ -83,7 +82,7 @@ export class IdentitiesValidationService {
8382
}
8483

8584
if (reject) {
86-
throw new ValidationSchemaException(validations);
85+
throw new ValidationSchemaException({ validations });
8786
}
8887
return Promise.resolve({ message: 'Validation succeeded' });
8988
}

0 commit comments

Comments
 (0)