Skip to content

Commit 216b108

Browse files
bhavanakarwadeKambleSahil3
authored andcommitted
fix: issues related nested attributes in issuance process (#1194)
* fix: issues related nested attributes in issuance process Signed-off-by: bhavanakarwade <[email protected]> * fix: added statuscode Signed-off-by: bhavanakarwade <[email protected]> * fix: required field validation for request id field Signed-off-by: bhavanakarwade <[email protected]> --------- Signed-off-by: bhavanakarwade <[email protected]> Signed-off-by: Sahil Kamble <[email protected]>
1 parent b9d49b6 commit 216b108

File tree

10 files changed

+283
-128
lines changed

10 files changed

+283
-128
lines changed

apps/api-gateway/src/dtos/create-schema.dto.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ApiExtraModels, ApiProperty, ApiPropertyOptional, getSchemaPath } from '@nestjs/swagger';
12
import {
23
ArrayMinSize,
34
IsArray,
@@ -13,11 +14,9 @@ import {
1314
ValidateIf,
1415
ValidateNested
1516
} from 'class-validator';
16-
17-
import { ApiExtraModels, ApiProperty, ApiPropertyOptional, getSchemaPath } from '@nestjs/swagger';
18-
import { plainToClass, Transform, Type } from 'class-transformer';
19-
import { IsNotSQLInjection, trim } from '@credebl/common/cast.helper';
2017
import { IndySchemaDataType, JSONSchemaType, SchemaTypeEnum, W3CSchemaDataType } from '@credebl/enum/enum';
18+
import { IsNotSQLInjection, ValidateNestedStructureFields, trim } from '@credebl/common/cast.helper';
19+
import { Transform, Type, plainToClass } from 'class-transformer';
2120

2221
export class W3CAttributeValue {
2322
@ApiProperty()
@@ -40,6 +39,7 @@ export class W3CAttributeValue {
4039
@IsEnum(W3CSchemaDataType, {
4140
message: `Schema data type must be one of [${Object.values(W3CSchemaDataType).join(', ')}]`
4241
})
42+
@ValidateNestedStructureFields()
4343
schemaDataType: W3CSchemaDataType;
4444

4545
@ApiProperty()

apps/api-gateway/src/issuance/dtos/issuance.dto.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import {
1313
IsObject,
1414
IsOptional,
1515
IsString,
16-
IsUrl,
1716
IsUUID,
17+
IsUrl,
1818
MaxLength,
1919
ValidateNested
2020
} from 'class-validator';
21+
import { AutoAccept, SchemaType, SortValue } from '@credebl/enum/enum';
2122
import { IsCredentialJsonLdContext, SingleOrArray } from '../utils/helper';
2223
import {
2324
IssueCredentialType,
@@ -27,7 +28,6 @@ import {
2728
} from '../interfaces';
2829
import { Transform, Type } from 'class-transformer';
2930

30-
import { AutoAccept, SchemaType, SortValue } from '@credebl/enum/enum';
3131
import { SortFields } from 'apps/connection/src/enum/connection.enum';
3232
import { trim } from '@credebl/common/cast.helper';
3333

@@ -487,6 +487,8 @@ export class OOBCredentialDtoWithEmail {
487487

488488
imageUrl?: string;
489489

490+
isValidateSchema?: boolean;
491+
490492
orgId: string;
491493
}
492494

@@ -654,8 +656,7 @@ export class FileQuery {
654656
}
655657

656658
export class RequestIdQuery {
657-
@ApiPropertyOptional({ required: false })
658-
@IsOptional()
659+
@ApiProperty()
659660
@IsString({ message: 'requestId should be string' })
660661
@IsNotEmpty({ message: 'requestId Id is required' })
661662
@Transform(({ value }) => trim(value))

apps/api-gateway/src/issuance/issuance.controller.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ import {
3333
ApiQuery,
3434
ApiExcludeEndpoint,
3535
ApiConsumes,
36-
ApiBody
36+
ApiBody,
37+
ApiNotFoundResponse
3738
} from '@nestjs/swagger';
3839
import { AuthGuard } from '@nestjs/passport';
3940
import { ApiResponseDto } from '../dtos/apiResponse.dto';
@@ -79,6 +80,7 @@ import { IssueCredentialDto } from './dtos/multi-connection.dto';
7980
import { SchemaType } from '@credebl/enum/enum';
8081
import { CommonConstants } from '../../../../libs/common/src/common.constant';
8182
import { TrimStringParamPipe } from '@credebl/common/cast.helper';
83+
import { NotFoundErrorDto } from '../dtos/not-found-error.dto';
8284
@Controller()
8385
@UseFilters(CustomExceptionFilter)
8486
@ApiTags('credentials')
@@ -255,6 +257,7 @@ export class IssuanceController {
255257
@ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto })
256258
@ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto })
257259
@ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto })
260+
@ApiNotFoundResponse({ status: HttpStatus.NOT_FOUND, description: 'Not Found', type: NotFoundErrorDto })
258261
@ApiBearerAuth()
259262
@Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER)
260263
@UseGuards(AuthGuard('jwt'), OrgRolesGuard)
@@ -287,7 +290,11 @@ export class IssuanceController {
287290
.status(HttpStatus.OK)
288291
.send(templateData.fileContent);
289292
} catch (error) {
290-
return res.status(error.status || error.error.code || HttpStatus.INTERNAL_SERVER_ERROR).json(error.error);
293+
return res
294+
.status(error.statusCode || HttpStatus.INTERNAL_SERVER_ERROR)
295+
.header('Content-Type', 'application/json')
296+
.header('Content-Disposition', '')
297+
.send(error);
291298
}
292299
}
293300
/**
@@ -380,7 +387,7 @@ export class IssuanceController {
380387
isValidateSchema
381388
};
382389

383-
const importCsvDetails = await this.issueCredentialService.uploadCSVTemplate(uploadedfileDetails);
390+
const importCsvDetails = await this.issueCredentialService.uploadCSVTemplate(uploadedfileDetails, orgId);
384391
const finalResponse: IResponseType = {
385392
statusCode: HttpStatus.CREATED,
386393
message: ResponseMessages.issuance.success.importCSV,
@@ -743,6 +750,11 @@ export class IssuanceController {
743750
summary: `Issuer create a credential offer`,
744751
description: `Issuer creates a credential offer and sends it to the holder`
745752
})
753+
@ApiQuery({
754+
name: 'isValidateSchema',
755+
type: Boolean,
756+
required: false
757+
})
746758
@ApiQuery({
747759
name: 'credentialType',
748760
enum: IssueCredentialType
@@ -763,10 +775,12 @@ export class IssuanceController {
763775
orgId: string,
764776
@Body() issueCredentialDto: IssueCredentialDto,
765777
@Res() res: Response,
766-
@Query('credentialType') credentialType: IssueCredentialType = IssueCredentialType.INDY
778+
@Query('credentialType') credentialType: IssueCredentialType = IssueCredentialType.INDY,
779+
@Query('isValidateSchema') isValidateSchema: boolean = true
767780
): Promise<Response> {
768781
issueCredentialDto.orgId = orgId;
769782
issueCredentialDto.credentialType = credentialType;
783+
issueCredentialDto.isValidateSchema = isValidateSchema;
770784

771785
const credOffer = issueCredentialDto?.credentialData || [];
772786

@@ -832,15 +846,23 @@ export class IssuanceController {
832846
name: 'credentialType',
833847
enum: IssueCredentialType
834848
})
849+
@ApiQuery({
850+
name: 'isValidateSchema',
851+
type: Boolean,
852+
required: false
853+
})
835854
async outOfBandCredentialOffer(
836855
@User() user: IUserRequest,
837856
@Body() outOfBandCredentialDto: OOBCredentialDtoWithEmail,
838857
@Param('orgId') orgId: string,
839858
@Res() res: Response,
840-
@Query('credentialType') credentialType: IssueCredentialType = IssueCredentialType.INDY
859+
@Query('credentialType') credentialType: IssueCredentialType = IssueCredentialType.INDY,
860+
@Query('isValidateSchema') isValidateSchema: boolean = true
841861
): Promise<Response> {
842862
outOfBandCredentialDto.orgId = orgId;
843863
outOfBandCredentialDto.credentialType = credentialType;
864+
outOfBandCredentialDto.isValidateSchema = isValidateSchema;
865+
844866
const credOffer = outOfBandCredentialDto?.credentialOffer || [];
845867
if (IssueCredentialType.INDY !== credentialType && IssueCredentialType.JSONLD !== credentialType) {
846868
throw new NotFoundException(ResponseMessages.issuance.error.invalidCredentialType);

apps/api-gateway/src/issuance/issuance.service.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export class IssuanceService extends BaseService {
4949
protocolVersion: issueCredentialDto.protocolVersion,
5050
autoAcceptCredential: issueCredentialDto.autoAcceptCredential,
5151
credentialType: issueCredentialDto.credentialType,
52+
isValidateSchema: issueCredentialDto.isValidateSchema,
5253
user
5354
};
5455

@@ -172,8 +173,8 @@ export class IssuanceService extends BaseService {
172173
.response;
173174
}
174175

175-
async uploadCSVTemplate(importFileDetails: UploadedFileDetails): Promise<{ response: object }> {
176-
const payload = { importFileDetails };
176+
async uploadCSVTemplate(importFileDetails: UploadedFileDetails, orgId: string): Promise<{ response: object }> {
177+
const payload = { importFileDetails, orgId };
177178
return this.natsClient.sendNats(this.issuanceProxy, 'upload-csv-template', payload);
178179
}
179180

apps/issuance/interfaces/issuance.interfaces.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// eslint-disable-next-line camelcase
22
import { AutoAccept, SchemaType } from '@credebl/enum/enum';
3-
import { IUserRequest } from '@credebl/user-request/user-request.interface';
43
import { Prisma, organisation } from '@prisma/client';
4+
5+
import { IPrettyVc } from '@credebl/common/interfaces/issuance.interface';
6+
import { IUserRequest } from '@credebl/user-request/user-request.interface';
57
import { IUserRequestInterface } from 'apps/agent-service/src/interface/agent-service.interface';
68
import { IssueCredentialType } from 'apps/api-gateway/src/issuance/interfaces';
7-
import { IPrettyVc } from '@credebl/common/interfaces/issuance.interface';
89

910
export interface IAttributes {
1011
attributeName: string;
@@ -32,6 +33,7 @@ export interface IIssuance {
3233
willConfirm?: boolean;
3334
label?: string;
3435
credentialType: string;
36+
isValidateSchema?: string;
3537
}
3638

3739
interface IIndy {
@@ -178,6 +180,7 @@ export interface OutOfBandCredentialOfferPayload {
178180
imageUrl?: string;
179181
autoAcceptCredential?: string;
180182
credentialType?: IssueCredentialType;
183+
isValidateSchema?: boolean;
181184
}
182185

183186
export interface OutOfBandCredentialOffer {
Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
1+
import {
2+
IClientDetails,
3+
IIssuance,
4+
IIssueCredentials,
5+
IIssueCredentialsDefinitions,
6+
ImportFileDetails,
7+
IssueCredentialWebhookPayload,
8+
OutOfBandCredentialOffer,
9+
PreviewRequest,
10+
TemplateDetailsInterface
11+
} from '../interfaces/issuance.interfaces';
12+
import {
13+
ICredentialOfferResponse,
14+
IDeletedIssuanceRecords,
15+
IIssuedCredential
16+
} from '@credebl/common/interfaces/issuance.interface';
17+
118
import { Controller } from '@nestjs/common';
2-
import { MessagePattern } from '@nestjs/microservices';
3-
import { IClientDetails, IIssuance, IIssueCredentials, IIssueCredentialsDefinitions, ImportFileDetails, IssueCredentialWebhookPayload, OutOfBandCredentialOffer, PreviewRequest, TemplateDetailsInterface } from '../interfaces/issuance.interfaces';
419
import { IssuanceService } from './issuance.service';
5-
import { ICredentialOfferResponse, IDeletedIssuanceRecords, IIssuedCredential } from '@credebl/common/interfaces/issuance.interface';
20+
import { MessagePattern } from '@nestjs/microservices';
621
import { OOBIssueCredentialDto } from 'apps/api-gateway/src/issuance/dtos/issuance.dto';
722
import { user } from '@prisma/client';
823

924
@Controller()
1025
export class IssuanceController {
11-
constructor(private readonly issuanceService: IssuanceService) { }
26+
constructor(private readonly issuanceService: IssuanceService) {}
1227

1328
@MessagePattern({ cmd: 'get-issuance-records' })
14-
async getIssuanceRecordsByOrgId(payload: { orgId: string, userId: string }): Promise<number> {
29+
async getIssuanceRecordsByOrgId(payload: { orgId: string; userId: string }): Promise<number> {
1530
const { orgId } = payload;
1631
return this.issuanceService.getIssuanceRecords(orgId);
1732
}
@@ -22,7 +37,7 @@ export class IssuanceController {
2237
}
2338

2439
@MessagePattern({ cmd: 'send-credential-create-offer-oob' })
25-
async sendCredentialOutOfBand(payload: OOBIssueCredentialDto): Promise<{response: object;}> {
40+
async sendCredentialOutOfBand(payload: OOBIssueCredentialDto): Promise<{ response: object }> {
2641
return this.issuanceService.sendCredentialOutOfBand(payload);
2742
}
2843

@@ -38,7 +53,6 @@ export class IssuanceController {
3853
return this.issuanceService.getIssueCredentialsbyCredentialRecordId(user, credentialRecordId, orgId);
3954
}
4055

41-
4256
@MessagePattern({ cmd: 'webhook-get-issue-credential' })
4357
async getIssueCredentialWebhook(payload: IssueCredentialWebhookPayload): Promise<object> {
4458
return this.issuanceService.getIssueCredentialWebhook(payload);
@@ -52,63 +66,71 @@ export class IssuanceController {
5266

5367
@MessagePattern({ cmd: 'download-csv-template-for-bulk-operation' })
5468
async downloadBulkIssuanceCSVTemplate(payload: {
55-
orgId: string, templateDetails: TemplateDetailsInterface
69+
orgId: string;
70+
templateDetails: TemplateDetailsInterface;
5671
}): Promise<object> {
57-
const {templateDetails} = payload;
58-
return this.issuanceService.downloadBulkIssuanceCSVTemplate(templateDetails);
72+
const { orgId, templateDetails } = payload;
73+
return this.issuanceService.downloadBulkIssuanceCSVTemplate(orgId, templateDetails);
5974
}
6075

6176
@MessagePattern({ cmd: 'upload-csv-template' })
62-
async uploadCSVTemplate(payload: {
63-
importFileDetails: ImportFileDetails
64-
}): Promise<string> {
65-
return this.issuanceService.uploadCSVTemplate(payload.importFileDetails);
77+
async uploadCSVTemplate(payload: { importFileDetails: ImportFileDetails; orgId: string }): Promise<string> {
78+
return this.issuanceService.uploadCSVTemplate(payload.importFileDetails, payload.orgId);
6679
}
6780

6881
@MessagePattern({ cmd: 'preview-csv-details' })
69-
async previewCSVDetails(payload: { requestId: string, previewFileDetails: PreviewRequest }): Promise<object> {
70-
return this.issuanceService.previewFileDataForIssuance(
71-
payload.requestId,
72-
payload.previewFileDetails
73-
);
82+
async previewCSVDetails(payload: { requestId: string; previewFileDetails: PreviewRequest }): Promise<object> {
83+
return this.issuanceService.previewFileDataForIssuance(payload.requestId, payload.previewFileDetails);
7484
}
7585

7686
@MessagePattern({ cmd: 'issued-file-details' })
77-
async issuedFiles(payload: { orgId: string, fileParameter: PreviewRequest }): Promise<object> {
78-
return this.issuanceService.issuedFileDetails(
79-
payload.orgId,
80-
payload.fileParameter
81-
);
87+
async issuedFiles(payload: { orgId: string; fileParameter: PreviewRequest }): Promise<object> {
88+
return this.issuanceService.issuedFileDetails(payload.orgId, payload.fileParameter);
8289
}
8390
@MessagePattern({ cmd: 'issued-file-data' })
84-
async getFileDetailsByFileId(payload: { fileId: string, fileParameter: PreviewRequest }): Promise<object> {
85-
return this.issuanceService.getFileDetailsByFileId(
86-
payload.fileId,
87-
payload.fileParameter
88-
);
91+
async getFileDetailsByFileId(payload: { fileId: string; fileParameter: PreviewRequest }): Promise<object> {
92+
return this.issuanceService.getFileDetailsByFileId(payload.fileId, payload.fileParameter);
8993
}
9094

91-
9295
@MessagePattern({ cmd: 'issue-bulk-credentials' })
93-
async issueBulkCredentials(payload: { requestId: string, orgId: string, clientDetails: IClientDetails, reqPayload: ImportFileDetails, isValidateSchema: boolean }): Promise<string> {
94-
return this.issuanceService.issueBulkCredential(payload.requestId, payload.orgId, payload.clientDetails, payload.reqPayload, payload.isValidateSchema);
96+
async issueBulkCredentials(payload: {
97+
requestId: string;
98+
orgId: string;
99+
clientDetails: IClientDetails;
100+
reqPayload: ImportFileDetails;
101+
isValidateSchema: boolean;
102+
}): Promise<string> {
103+
return this.issuanceService.issueBulkCredential(
104+
payload.requestId,
105+
payload.orgId,
106+
payload.clientDetails,
107+
payload.reqPayload,
108+
payload.isValidateSchema
109+
);
95110
}
96111

97112
@MessagePattern({ cmd: 'retry-bulk-credentials' })
98-
async retryeBulkCredentials(payload: { fileId: string, orgId: string, clientDetails: IClientDetails, isValidateSchema?: boolean }): Promise<string> {
99-
return this.issuanceService.retryBulkCredential(payload.fileId, payload.orgId, payload.clientDetails, payload.isValidateSchema);
113+
async retryeBulkCredentials(payload: {
114+
fileId: string;
115+
orgId: string;
116+
clientDetails: IClientDetails;
117+
isValidateSchema?: boolean;
118+
}): Promise<string> {
119+
return this.issuanceService.retryBulkCredential(
120+
payload.fileId,
121+
payload.orgId,
122+
payload.clientDetails,
123+
payload.isValidateSchema
124+
);
100125
}
101126

102127
@MessagePattern({ cmd: 'delete-issuance-records' })
103-
async deleteIssuanceRecords(payload: {orgId: string, userDetails: user}): Promise<IDeletedIssuanceRecords> {
128+
async deleteIssuanceRecords(payload: { orgId: string; userDetails: user }): Promise<IDeletedIssuanceRecords> {
104129
const { orgId, userDetails } = payload;
105130
return this.issuanceService.deleteIssuanceRecords(orgId, userDetails);
106131
}
107132
@MessagePattern({ cmd: 'issued-file-data-and-file-details' })
108-
async getFileDetailsAndFileDataByFileId(payload: { fileId: string, orgId: string }): Promise<object> {
109-
return this.issuanceService.getFileDetailsAndFileDataByFileId(
110-
payload.fileId,
111-
payload.orgId
112-
);
133+
async getFileDetailsAndFileDataByFileId(payload: { fileId: string; orgId: string }): Promise<object> {
134+
return this.issuanceService.getFileDetailsAndFileDataByFileId(payload.fileId, payload.orgId);
113135
}
114-
}
136+
}

0 commit comments

Comments
 (0)