Skip to content

Commit 12e763d

Browse files
Merge pull request #1090 from credebl/feat/versioning-of-send-proof-request-API
feat: API versioning changes for verification micro-service and for send proof request API
2 parents 05c9590 + 02a2eff commit 12e763d

File tree

10 files changed

+309
-141
lines changed

10 files changed

+309
-141
lines changed

.env.demo

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ AFJ_AGENT_ENDPOINT_PATH=/agent-provisioning/AFJ/endpoints/
126126

127127
AGENT_PROTOCOL=http
128128
OOB_BATCH_SIZE=10
129+
PROOF_REQ_CONN_LIMIT=10
129130
MAX_ORG_LIMIT=10
130131
FIDO_API_ENDPOINT=http://localhost:8000
131132

@@ -135,4 +136,8 @@ ELK_LOG=true // ELK flag
135136
LOG_LEVEL=debug // ELK log level
136137
ELK_LOG_PATH = "http://localhost:9200/" // ELK log path
137138
ELK_USERNAME=elastic // ELK user username
138-
ELK_PASSWORD=xxxxxx // ELK user password
139+
ELK_PASSWORD=xxxxxx // ELK user password
140+
141+
ORGANIZATION=credebl
142+
CONTEXT=platform
143+
APP=api

.env.sample

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ PLATFORM_ID=
9898
PLATFORM_PROFILE_MODE= // Please provide your environment name
9999

100100
OOB_BATCH_SIZE=10
101+
PROOF_REQ_CONN_LIMIT=10
101102

102103
AFJ_AGENT_ENDPOINT_PATH=/apps/agent-provisioning/AFJ/endpoints/
103104
DATABASE_URL="postgresql://postgres:xxxxxx@localhost:5432/postgres?schema=public" #Provide supabase postgres URL and Use the correct user/pwd, IP Address
@@ -162,3 +163,7 @@ LOG_LEVEL=debug // ELK log level
162163
ELK_LOG_PATH = "http://localhost:9200/" // ELK log path
163164
ELK_USERNAME=elastic // ELK user username
164165
ELK_PASSWORD=xxxxxx // ELK user password
166+
167+
ORGANIZATION=credebl
168+
CONTEXT=platform
169+
APP=api

apps/api-gateway/src/main.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as dotenv from 'dotenv';
22
import * as express from 'express';
33

44
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
5-
import { Logger, ValidationPipe } from '@nestjs/common';
5+
import { Logger, ValidationPipe, VERSION_NEUTRAL, VersioningType } from '@nestjs/common';
66

77
import { AppModule } from './app.module';
88
import { HttpAdapterHost, NestFactory } from '@nestjs/core';
@@ -57,6 +57,11 @@ async function bootstrap(): Promise<void> {
5757
.addServer(`${process.env.API_GATEWAY_PROTOCOL}://${process.env.API_GATEWAY_HOST}`)
5858
.build();
5959

60+
app.enableVersioning({
61+
type: VersioningType.URI,
62+
defaultVersion: ['1']
63+
});
64+
6065
const document = SwaggerModule.createDocument(app, options);
6166
SwaggerModule.setup('api', app, document);
6267
const httpAdapter = app.get(HttpAdapterHost);
@@ -70,6 +75,11 @@ async function bootstrap(): Promise<void> {
7075
});
7176
}
7277

78+
app.enableVersioning({
79+
type: VersioningType.URI,
80+
defaultVersion: ['1', VERSION_NEUTRAL]
81+
});
82+
7383
app.use(express.static('uploadedFiles/holder-profile'));
7484
app.use(express.static('uploadedFiles/org-logo'));
7585
app.use(express.static('uploadedFiles/tenant-logo'));

apps/api-gateway/src/verification/dto/request-proof.dto.ts

Lines changed: 63 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ArrayNotEmpty, IsArray, IsBoolean, IsEmail, IsEnum, IsNotEmpty, IsNumberString, IsObject, IsOptional, IsString, ValidateIf, ValidateNested, IsUUID, ArrayUnique, ArrayMaxSize } from 'class-validator';
1+
import { ArrayNotEmpty, IsArray, IsBoolean, IsEmail, IsEnum, IsNotEmpty, IsNumberString, IsObject, IsOptional, IsString, ValidateIf, ValidateNested, IsUUID, ArrayUnique, ArrayMaxSize, ArrayMinSize } from 'class-validator';
22
import { trim } from '@credebl/common/cast.helper';
33
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
44
import { Transform, Type } from 'class-transformer';
@@ -14,7 +14,7 @@ export class ProofRequestAttribute {
1414
attributeName?: string;
1515

1616
@ValidateIf((obj) => obj.attributeName === undefined)
17-
@IsArray({ message: 'attributeNames must be an array.' })
17+
@IsArray({ message: 'attributeNames must be an array' })
1818
@ArrayNotEmpty({ message: 'array can not be empty' })
1919
@IsString({ each: true })
2020
@IsNotEmpty({ each: true, message: 'each element cannot be empty' })
@@ -23,23 +23,25 @@ export class ProofRequestAttribute {
2323
@ApiPropertyOptional()
2424
@IsString()
2525
@IsOptional()
26+
@IsNotEmpty({ message: 'schemaId is required' })
2627
schemaId?: string;
2728

2829
@ApiPropertyOptional()
29-
@IsString()
30-
@IsOptional()
31-
@IsNotEmpty({ message: 'condition is required.' })
30+
@ValidateIf((obj) => obj.value !== undefined || obj.condition !== undefined)
31+
@IsNotEmpty({ message: 'condition is required' })
32+
@IsString({ message: 'condition must be a string' })
3233
condition?: string;
33-
34+
3435
@ApiPropertyOptional()
35-
@IsOptional()
36-
@IsNotEmpty({ message: 'value is required.' })
37-
@IsNumberString({}, { message: 'Value must be a number' })
36+
@ValidateIf((obj) => obj.condition !== undefined || obj.value !== undefined)
37+
@IsNotEmpty({ message: 'value is required' })
38+
@IsNumberString({}, { message: 'value must be a number' })
3839
value?: string;
3940

4041
@ApiPropertyOptional()
4142
@IsString()
4243
@IsOptional()
44+
@IsNotEmpty({ message: 'credDefId is required' })
4345
credDefId?: string;
4446
}
4547

@@ -54,7 +56,7 @@ class ProofPayload {
5456
@IsString({ message: 'parentThreadId must be in string' })
5557
@IsNotEmpty({ message: 'please provide valid parentThreadId' })
5658
@IsOptional()
57-
parentThreadId: string;
59+
parentThreadId?: string;
5860

5961
@ApiPropertyOptional()
6062
@IsBoolean({ message: 'willConfirm must be in boolean' })
@@ -72,14 +74,14 @@ class ProofPayload {
7274
export class Fields {
7375
@ApiProperty()
7476
@IsArray()
75-
@IsNotEmpty({ message: 'path is required.' })
77+
@IsNotEmpty({ message: 'path is required' })
7678
path: string[];
7779
}
7880

7981
export class Constraints {
8082
@ApiProperty({type: () => [Fields]})
8183
@IsOptional()
82-
@IsNotEmpty({ message: 'Fields are required.' })
84+
@IsNotEmpty({ message: 'Fields are required' })
8385
@ValidateNested()
8486
@Type(() => Fields)
8587
fields: Fields[];
@@ -88,40 +90,40 @@ export class Constraints {
8890

8991
export class Schema {
9092
@ApiProperty()
91-
@IsNotEmpty({ message: 'uri is required.' })
93+
@IsNotEmpty({ message: 'uri is required' })
9294
@IsString()
9395
uri:string;
9496

9597
}
9698
export class InputDescriptors {
9799
@ApiProperty()
98-
@IsNotEmpty({ message: 'id is required.' })
100+
@IsNotEmpty({ message: 'id is required' })
99101
@IsString()
100102
id:string;
101103

102104
@ApiProperty()
103105
@IsString()
104106
@IsOptional()
105-
@IsNotEmpty({ message: 'name is required.' })
107+
@IsNotEmpty({ message: 'name is required' })
106108
name:string;
107109

108110
@ApiProperty()
109111
@IsString()
110112
@IsOptional()
111-
@IsNotEmpty({ message: 'purpose is required.' })
113+
@IsNotEmpty({ message: 'purpose is required' })
112114
purpose:string;
113115

114116

115117
@ApiProperty({type: () => [Schema]})
116-
@IsNotEmpty({ message: 'schema is required.' })
118+
@IsNotEmpty({ message: 'schema is required' })
117119
@ValidateNested()
118120
@Type(() => Schema)
119121
schema:Schema[];
120122

121123

122124
@ApiProperty({type: () => Constraints})
123125
@IsOptional()
124-
@IsNotEmpty({ message: 'Constraints are required.' })
126+
@IsNotEmpty({ message: 'Constraints are required' })
125127
@ValidateNested()
126128
@Type(() => Constraints)
127129
constraints:Constraints;
@@ -131,19 +133,19 @@ export class InputDescriptors {
131133
export class ProofRequestPresentationDefinition {
132134

133135
@IsString()
134-
@IsNotEmpty({ message: 'id is required.' })
136+
@IsNotEmpty({ message: 'id is required' })
135137
id: string;
136138

137139
@IsString()
138140
@IsOptional()
139141
name: string;
140142

141-
@ApiProperty({type: () => [InputDescriptors]})
142-
@IsNotEmpty({ message: 'inputDescriptors is required.' })
143+
@ApiProperty({type: () => [InputDescriptors]})
143144
@IsArray({ message: 'inputDescriptors must be an array' })
144-
@IsObject({ each: true })
145+
@IsNotEmpty({ message: 'inputDescriptors is required' })
146+
@ArrayMinSize(1)
147+
@ValidateNested({each:true})
145148
@Type(() => InputDescriptors)
146-
@ValidateNested()
147149
// eslint-disable-next-line camelcase
148150
input_descriptors:InputDescriptors[];
149151
}
@@ -162,7 +164,7 @@ export class ProofRequestAttributeDto {
162164
type: () => [ProofRequestAttribute]
163165
})
164166
@IsArray({ message: 'attributes must be in array' })
165-
@ValidateNested()
167+
@ValidateNested({ each: true })
166168
@IsObject({ each: true })
167169
@IsNotEmpty({ message: 'please provide valid attributes' })
168170
@Type(() => ProofRequestAttribute)
@@ -191,13 +193,7 @@ export class IndyDto {
191193
indy: ProofRequestAttributeDto;
192194
}
193195

194-
export class RequestProofDto extends ProofPayload {
195-
@ApiProperty()
196-
@IsString()
197-
@Transform(({ value }) => trim(value))
198-
@IsUUID()
199-
@IsNotEmpty({ message: 'connectionId is required.' })
200-
connectionId: string;
196+
export class RequestProofDtoBase extends ProofPayload {
201197

202198
@ApiProperty({
203199
'example':
@@ -213,7 +209,7 @@ export class RequestProofDto extends ProofPayload {
213209
}
214210
]
215211
}
216-
},
212+
},
217213
type: () => [IndyDto]
218214
})
219215
@IsOptional()
@@ -222,12 +218,13 @@ export class RequestProofDto extends ProofPayload {
222218
@IsNotEmpty({ message: 'ProofFormatDto must not be empty' })
223219
@Type(() => IndyDto)
224220
proofFormats?: IndyDto;
225-
221+
226222
@ApiProperty({
227223
'example':
228224
{
229-
id: '32f54163-7166-48f1-93d8-ff217bdb0653',
230-
inputDescriptors: [
225+
id: '32f54163-7166-48f1-93d8-ff217bdb0653',
226+
// eslint-disable-next-line camelcase
227+
input_descriptors: [
231228
{
232229
'id': 'healthcare_input_1',
233230
'name': 'Medical History',
@@ -240,7 +237,7 @@ export class RequestProofDto extends ProofPayload {
240237
'constraints': {
241238
'fields': [
242239
{
243-
'path': ['$.PatientID']
240+
'path': ['$.credentialSubject.PatientID']
244241
}
245242
]
246243
}
@@ -260,20 +257,44 @@ export class RequestProofDto extends ProofPayload {
260257
@IsOptional()
261258
@IsString({ message: 'comment must be in string' })
262259
comment: string;
263-
260+
264261
type:ProofRequestType;
265-
262+
266263
orgId: string;
267-
268-
@ApiPropertyOptional()
264+
265+
@ApiPropertyOptional({enum:AutoAccept})
269266
@IsString({ message: 'auto accept proof must be in string' })
270267
@IsNotEmpty({ message: 'please provide valid auto accept proof' })
271268
@IsOptional()
272269
@IsEnum(AutoAccept, {
273-
message: `Invalid auto accept proof. It should be one of: ${Object.values(AutoAccept).join(', ')}`
270+
message: `Invalid auto accept proof. It should be one of: ${Object.values(AutoAccept).join(', ')}`
274271
})
275272
autoAcceptProof: AutoAccept;
273+
version: string;
276274
}
275+
export class RequestProofDtoV1 extends RequestProofDtoBase {
276+
@ApiProperty({
277+
example: '32f54163-7166-48f1-93d8-ff217bdb0653'
278+
})
279+
@IsNotEmpty({ message: 'connectionId is required' })
280+
@IsString({ message: 'connectionId must be a string' })
281+
@IsUUID()
282+
connectionId:string;
283+
}
284+
285+
286+
export class RequestProofDtoV2 extends RequestProofDtoBase {
287+
@ApiProperty({
288+
example: ['32f54163-7166-48f1-93d8-ff217bdb0653']
289+
})
290+
@IsNotEmpty({ each: true, message: 'connectionId array elements must not be empty' })
291+
@IsArray({ message: 'connectionId must be an array' })
292+
@ArrayMinSize(1, { message: 'connectionId must contain at least 1 element' })
293+
@ArrayMaxSize(Number(process.env.PROOF_REQ_CONN_LIMIT), { message: `Limit reached (${process.env.PROOF_REQ_CONN_LIMIT} connections max).` })
294+
@IsUUID('all', { each: true, message: 'Each connectionId must be a valid UUID' })
295+
connectionId: string[];
296+
}
297+
277298

278299
export class OutOfBandRequestProof extends ProofPayload {
279300
@ApiProperty({
@@ -421,7 +442,7 @@ export class SendProofRequestPayload {
421442
@ApiProperty({ example: true })
422443
@IsBoolean()
423444
@IsOptional()
424-
@IsNotEmpty({message:'Please provide the flag for shorten url.'})
445+
@IsNotEmpty({message:'Please provide the flag for shorten url'})
425446
isShortenUrl?: boolean;
426447

427448
@ApiPropertyOptional()

apps/api-gateway/src/verification/enum/verification.enum.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,27 @@ export enum SortFields {
88
export enum ProofRequestType {
99
INDY = 'indy',
1010
PRESENTATIONEXCHANGE = 'presentationExchange'
11+
}
12+
13+
export enum VerificationMethodLabel {
14+
REQUEST_PROOF = 'request-proof'
15+
}
16+
17+
export enum ProtocolVersionType {
18+
PROTOCOL_VERSION_1 = 'v1',
19+
PROTOCOL_VERSION_2 = 'v2'
20+
21+
}
22+
23+
export enum ProofRequestLabel {
24+
PROOF_REQUEST = 'Proof Request'
25+
}
26+
27+
export enum ProofVersion {
28+
PROOF_VERSION = '1.0'
29+
}
30+
31+
export enum API_Version {
32+
VERSION_1 = 'v1',
33+
version_neutral = 'version_neutral'
1134
}

0 commit comments

Comments
 (0)