Skip to content

Commit f6d0b25

Browse files
committed
save split des classes
1 parent 67e08c1 commit f6d0b25

12 files changed

+857
-699
lines changed

src/core/backends/backends.service.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {
22
BadRequestException,
3-
HttpException,
43
HttpStatus,
4+
HttpException,
55
Injectable,
66
RequestTimeoutException,
77
UnprocessableEntityException,
@@ -11,25 +11,24 @@ import { Document, ModifyResult, Query, Types } from 'mongoose';
1111
import { AbstractQueueProcessor } from '~/_common/abstracts/abstract.queue.processor';
1212
import { IdentityState } from '~/management/identities/_enums/states.enum';
1313
import { Identities } from '~/management/identities/_schemas/identities.schema';
14-
import { IdentitiesService } from '~/management/identities/identities.service';
14+
import { IdentitiesCrudService } from '~/management/identities/identities-crud.service';
1515
import { JobState } from '../jobs/_enums/state.enum';
1616
import { Jobs } from '../jobs/_schemas/jobs.schema';
1717
import { JobsService } from '../jobs/jobs.service';
1818
import { Tasks } from '../tasks/_schemas/tasks.schema';
1919
import { TasksService } from '../tasks/tasks.service';
2020
import { ActionType } from './_enum/action-type.enum';
2121
import { ExecuteJobOptions } from './_interfaces/execute-job-options.interface';
22-
import { BackendResultInterface } from "~/core/backends/_interfaces/backend-result.interface";
23-
import { WorkerResultInterface } from "~/core/backends/_interfaces/worker-result.interface";
24-
import {DataStatusEnum} from "~/management/identities/_enums/data-status";
22+
import { WorkerResultInterface } from '~/core/backends/_interfaces/worker-result.interface';
23+
import { DataStatusEnum } from '~/management/identities/_enums/data-status';
2524

2625
const DEFAULT_SYNC_TIMEOUT = 30_000;
2726

2827
@Injectable()
2928
export class BackendsService extends AbstractQueueProcessor {
3029
public constructor(
3130
protected moduleRef: ModuleRef,
32-
protected identitiesService: IdentitiesService,
31+
protected identitiesService: IdentitiesCrudService,
3332
protected jobsService: JobsService,
3433
protected tasksService: TasksService,
3534
) {
@@ -377,7 +376,7 @@ export class BackendsService extends AbstractQueueProcessor {
377376
},
378377
{
379378
...options?.job,
380-
jobId: (new Types.ObjectId()).toHexString(),
379+
jobId: (new Types.ObjectId() ).toHexString(),
381380
attempts: 1,
382381
},
383382
);
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import { BadRequestException, forwardRef, HttpException, Inject, Injectable } from '@nestjs/common';
2+
import { InjectModel } from '@nestjs/mongoose';
3+
import { Document, Model, ModifyResult, Query, Types } from 'mongoose';
4+
import { AbstractServiceSchema } from '~/_common/abstracts/abstract.service.schema';
5+
import { AbstractSchema } from '~/_common/abstracts/schemas/abstract.schema';
6+
import { ValidationConfigException, ValidationSchemaException } from '~/_common/errors/ValidationException';
7+
import { IdentitiesUpsertDto } from './_dto/identities.dto';
8+
import { IdentityState } from './_enums/states.enum';
9+
import { Identities } from './_schemas/identities.schema';
10+
import { IdentitiesValidationService } from './validations/identities.validation.service';
11+
import { FactorydriveService } from '@the-software-compagny/nestjs_module_factorydrive';
12+
import { BackendsService } from '~/core/backends/backends.service';
13+
import { construct, omit } from 'radash';
14+
import { toPlainAndCrush } from '~/_common/functions/to-plain-and-crush';
15+
import { createHash } from 'node:crypto';
16+
17+
@Injectable()
18+
export abstract class AbstractIdentitiesService extends AbstractServiceSchema {
19+
public constructor(
20+
@InjectModel(Identities.name) protected _model: Model<Identities>,
21+
protected readonly _validation: IdentitiesValidationService,
22+
protected readonly storage: FactorydriveService,
23+
@Inject(forwardRef(() => BackendsService)) protected readonly backends: BackendsService,
24+
) {
25+
super();
26+
}
27+
28+
protected handleValidationError(
29+
error: Error | HttpException,
30+
identity: Identities | IdentitiesUpsertDto,
31+
logPrefix: string,
32+
): any {
33+
if (error instanceof ValidationConfigException) {
34+
this.logger.error(`${logPrefix} Validation config error. ${JSON.stringify(error.getValidations())}`);
35+
throw new ValidationConfigException(error.getPayload());
36+
}
37+
38+
if (error instanceof ValidationSchemaException) {
39+
this.logger.warn(`${logPrefix} Validation schema error. ${JSON.stringify(error.getValidations())}`);
40+
identity.additionalFields.validations = error.getValidations() as any;
41+
// console.log('identity.state', identity.state)
42+
if (identity.state === IdentityState.TO_CREATE) {
43+
this.logger.warn(`${logPrefix} State set to TO_COMPLETE.`);
44+
identity.state = IdentityState.TO_COMPLETE;
45+
return identity;
46+
} else {
47+
this.logger.error(`${logPrefix} Validation schema error. ${JSON.stringify(error.getValidations())}`);
48+
throw new ValidationSchemaException(error.getPayload());
49+
}
50+
} else {
51+
this.logger.error(`${logPrefix} Unhandled error: ${error.message}`);
52+
throw error; // Rethrow the original error if it's not one of the handled types.
53+
}
54+
}
55+
56+
public transformNullsToString(obj) {
57+
if (obj === null) {
58+
return '';
59+
}
60+
61+
if (Array.isArray(obj)) {
62+
return obj.map(this.transformNullsToString);
63+
}
64+
65+
if (typeof obj === 'object' && !(obj instanceof Types.ObjectId)) {
66+
for (const key in obj) {
67+
if (obj[key] === null) {
68+
obj[key] = '';
69+
} else if (typeof obj[key] === 'object') {
70+
// console.log('key', key);
71+
obj[key] = this.transformNullsToString(obj[key]);
72+
}
73+
}
74+
}
75+
76+
return obj;
77+
}
78+
79+
protected async checkInetOrgPersonJpegPhoto(data: any) {
80+
if (data?.inetOrgPerson?.jpegPhoto) {
81+
let reqStorage;
82+
const [disk, path] = data.inetOrgPerson.jpegPhoto.split(':');
83+
84+
try {
85+
reqStorage = await this.storage.getDisk(disk).exists(path);
86+
} catch (error) {
87+
throw new BadRequestException(`Error while checking photo in storage: ${error.message}`);
88+
}
89+
90+
if (!reqStorage.exists) {
91+
throw new BadRequestException(`Photo not found in storage: ${data.inetOrgPerson.jpegPhoto}`);
92+
}
93+
}
94+
}
95+
protected async generateFingerprint<T extends AbstractSchema | Document>(
96+
identity: Identities,
97+
fingerprint?: string,
98+
): Promise<ModifyResult<Query<T, T, any, T>>> {
99+
if (!fingerprint) {
100+
fingerprint = await this.previewFingerprint(identity.toJSON());
101+
}
102+
103+
const updated = await this.model.findOneAndUpdate(
104+
{ _id: identity._id, fingerprint: { $ne: fingerprint } },
105+
{ fingerprint },
106+
{
107+
new: true,
108+
},
109+
);
110+
111+
if (!updated) {
112+
this.logger.verbose(`Fingerprint already up to date for <${identity._id}>.`);
113+
return identity as unknown as ModifyResult<Query<T, T, any, T>>;
114+
}
115+
116+
this.logger.debug(`Fingerprint updated for <${identity._id}>: ${fingerprint}`);
117+
return updated as unknown as ModifyResult<Query<T, T, any, T>>;
118+
}
119+
protected async previewFingerprint(identity: any): Promise<string> {
120+
const additionalFields = omit(identity.additionalFields, ['validations']);
121+
const data = JSON.stringify(
122+
construct(
123+
omit(
124+
toPlainAndCrush({
125+
inetOrgPerson: identity.inetOrgPerson,
126+
additionalFields,
127+
}) as any,
128+
[
129+
//TODO: add configurable fields to exclude
130+
/* 'additionalFields.attributes.supannPerson.supannOIDCGenre' */
131+
],
132+
),
133+
),
134+
);
135+
136+
const hash = createHash('sha256');
137+
hash.update(data);
138+
return hash.digest('hex').toString();
139+
}
140+
}

0 commit comments

Comments
 (0)