-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add W3C credential issuance (#555)
* feat:added w3c issuance Signed-off-by: pallavicoder <[email protected]> * feat:added jsonld credentail issuance Signed-off-by: pallavicoder <[email protected]> * feat:added W3C issuance Signed-off-by: pallavicoder <[email protected]> --------- Signed-off-by: pallavicoder <[email protected]>
- Loading branch information
1 parent
4bad987
commit 7e36041
Showing
8 changed files
with
396 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,109 @@ | ||
/* eslint-disable @typescript-eslint/array-type */ | ||
|
||
import { IsArray, IsNotEmpty, IsOptional, IsString, IsEmail, ArrayMaxSize, ValidateNested, ArrayMinSize, IsBoolean, IsDefined, MaxLength, IsEnum } from 'class-validator'; | ||
import { IsArray, IsNotEmpty, IsOptional, IsString, IsEmail, ArrayMaxSize, ValidateNested, ArrayMinSize, IsBoolean, IsDefined, MaxLength, IsEnum, IsObject} from 'class-validator'; | ||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; | ||
import { Transform, Type } from 'class-transformer'; | ||
import { trim } from '@credebl/common/cast.helper'; | ||
import { SortValue } from '../../enum'; | ||
import { SortFields } from 'apps/connection/src/enum/connection.enum'; | ||
import { AutoAccept } from '@credebl/enum/enum'; | ||
import { IssueCredentialType, JsonLdCredentialDetailCredentialStatusOptions, JsonLdCredentialDetailOptionsOptions, JsonObject } from '../interfaces'; | ||
import { IsCredentialJsonLdContext, SingleOrArray } from '../utils/helper'; | ||
|
||
class Issuer { | ||
@ApiProperty() | ||
@IsNotEmpty({ message: 'id is required' }) | ||
@Type(() => String) | ||
id:string | { id?: string }; | ||
} | ||
class Credential { | ||
@ApiProperty() | ||
@IsNotEmpty({ message: 'context is required' }) | ||
@IsCredentialJsonLdContext() | ||
'@context': Array<string | JsonObject>; | ||
|
||
@ApiProperty() | ||
@IsNotEmpty({ message: 'type is required' }) | ||
type: string[]; | ||
|
||
@ApiProperty() | ||
@IsString({ message: 'id should be string' }) | ||
@IsNotEmpty({ message: 'id is required' }) | ||
@Type(() => String) | ||
@IsOptional() | ||
id?:string; | ||
|
||
|
||
@ApiProperty() | ||
@ValidateNested({ each: true }) | ||
@Type(() => Issuer) | ||
issuer:Issuer; | ||
|
||
@ApiProperty() | ||
@IsString({ message: 'issuance date should be string' }) | ||
@IsNotEmpty({ message: 'issuance date is required' }) | ||
@Type(() => String) | ||
issuanceDate:string; | ||
|
||
@ApiProperty() | ||
@IsString({ message: 'expiration date should be string' }) | ||
@IsNotEmpty({ message: 'expiration date is required' }) | ||
@Type(() => String) | ||
@IsOptional() | ||
expirationDate?:string; | ||
|
||
@ApiProperty() | ||
@IsNotEmpty({ message: ' credential subject required' }) | ||
credentialSubject: SingleOrArray<JsonObject>; | ||
[key: string]: unknown | ||
|
||
} | ||
|
||
export class JsonLdCredentialDetailCredentialStatus { | ||
public constructor(options: JsonLdCredentialDetailCredentialStatusOptions) { | ||
if (options) { | ||
this.type = options.type; | ||
} | ||
} | ||
@IsString() | ||
public type!: string; | ||
} | ||
export class JsonLdCredentialDetailOptions { | ||
public constructor(options: JsonLdCredentialDetailOptionsOptions) { | ||
if (options) { | ||
this.proofPurpose = options.proofPurpose; | ||
this.created = options.created; | ||
this.domain = options.domain; | ||
this.challenge = options.challenge; | ||
this.credentialStatus = options.credentialStatus; | ||
this.proofType = options.proofType; | ||
} | ||
} | ||
|
||
@IsString() | ||
@IsNotEmpty({ message: 'proof purpose is required' }) | ||
public proofPurpose!: string; | ||
|
||
@IsString() | ||
@IsOptional() | ||
public created?: string; | ||
|
||
@IsString() | ||
@IsOptional() | ||
public domain?: string; | ||
|
||
@IsString() | ||
@IsOptional() | ||
public challenge?: string; | ||
|
||
@IsString() | ||
@IsNotEmpty({ message: 'proof type is required' }) | ||
public proofType!: string; | ||
|
||
@IsOptional() | ||
@IsObject() | ||
public credentialStatus?: JsonLdCredentialDetailCredentialStatus; | ||
} | ||
class Attribute { | ||
@ApiProperty() | ||
@IsString({ message: 'Attribute name should be string' }) | ||
|
@@ -33,7 +130,8 @@ class CredentialsIssuanceDto { | |
@IsNotEmpty({ message: 'Please provide valid credential definition id' }) | ||
@IsString({ message: 'credential definition id should be string' }) | ||
@Transform(({ value }) => value.trim()) | ||
credentialDefinitionId: string; | ||
@IsOptional() | ||
credentialDefinitionId?: string; | ||
|
||
@ApiProperty({ example: 'string' }) | ||
@IsNotEmpty({ message: 'Please provide valid comment' }) | ||
|
@@ -86,6 +184,12 @@ class CredentialsIssuanceDto { | |
}) | ||
autoAcceptCredential?: string; | ||
|
||
@ApiProperty({ example: 'jsonld' }) | ||
@IsNotEmpty({ message: 'Please provide credential type ' }) | ||
@Transform(({ value }) => trim(value).toLocaleLowerCase()) | ||
@IsOptional() | ||
credentialType:IssueCredentialType; | ||
|
||
orgId: string; | ||
} | ||
|
||
|
@@ -101,8 +205,29 @@ export class OOBIssueCredentialDto extends CredentialsIssuanceDto { | |
@IsArray() | ||
@ValidateNested({ each: true }) | ||
@ArrayMinSize(1) | ||
@IsOptional() | ||
@IsNotEmpty({ message: 'Please provide valid attributes' }) | ||
@Type(() => Attribute) | ||
attributes: Attribute[]; | ||
attributes?: Attribute[]; | ||
|
||
|
||
@ApiProperty() | ||
@IsNotEmpty({ message: 'Please provide valid credential' }) | ||
@IsObject({ message: 'credential should be an object' }) | ||
@Type(() => Credential) | ||
@IsOptional() | ||
@ValidateNested({ each: true }) | ||
credential?:Credential; | ||
|
||
|
||
@ApiProperty() | ||
@IsOptional() | ||
@IsNotEmpty({ message: 'Please provide valid options' }) | ||
@IsObject({ message: 'options should be an object' }) | ||
@ValidateNested({ each: true }) | ||
@Type(() => JsonLdCredentialDetailOptions) | ||
options?:JsonLdCredentialDetailOptions; | ||
|
||
} | ||
|
||
class CredentialOffer { | ||
|
@@ -111,7 +236,8 @@ class CredentialOffer { | |
@IsArray({ message: 'Attributes should be an array' }) | ||
@ValidateNested({ each: true }) | ||
@Type(() => Attribute) | ||
attributes: Attribute[]; | ||
@IsOptional() | ||
attributes?: Attribute[]; | ||
|
||
@ApiProperty({ example: '[email protected]' }) | ||
@IsEmail({}, { message: 'Please provide a valid email' }) | ||
|
@@ -121,6 +247,22 @@ class CredentialOffer { | |
@Transform(({ value }) => trim(value)) | ||
@Type(() => String) | ||
emailId: string; | ||
|
||
@IsNotEmpty({ message: 'Please provide valid credential' }) | ||
@IsObject({ message: 'credential should be an object' }) | ||
@Type(() => Credential) | ||
@IsOptional() | ||
@ValidateNested({ each: true }) | ||
credential?:Credential; | ||
|
||
@ApiProperty() | ||
@IsOptional() | ||
@IsNotEmpty({ message: 'Please provide valid options' }) | ||
@IsObject({ message: 'options should be an object' }) | ||
@ValidateNested({ each: true }) | ||
@Type(() => JsonLdCredentialDetailOptions) | ||
options?:JsonLdCredentialDetailOptions; | ||
|
||
} | ||
|
||
export class IssueCredentialDto extends OOBIssueCredentialDto { | ||
|
@@ -218,7 +360,39 @@ export class CredentialAttributes { | |
} | ||
|
||
export class OOBCredentialDtoWithEmail { | ||
@ApiProperty({ example: [{ 'emailId': '[email protected]', 'attributes': [{ 'value': 'string', 'name': 'string' }] }] }) | ||
@ApiProperty({ example: [ | ||
{ | ||
'emailId': '[email protected]', | ||
'credential': { | ||
'@context': [ | ||
'https://www.w3.org/2018/credentials/v1', | ||
'https://www.w3.org/2018/credentials/examples/v1' | ||
], | ||
'type': [ | ||
'VerifiableCredential', | ||
'UniversityDegreeCredential' | ||
], | ||
'issuer': { | ||
'id': 'did:key:z6Mkn72LVp3mq1fWSefkSMh5V7qrmGfCV4KH3K6SoTM21ouM' | ||
}, | ||
'issuanceDate': '2019-10-12T07:20:50.52Z', | ||
'credentialSubject': { | ||
'id': 'did:key:z6Mkn72LVp3mq1fWSefkSMh5V7qrmGfCV4KH3K6SoTM21ouM', | ||
'degree': { | ||
'type': 'BachelorDegree', | ||
'name': 'Bachelor of Science and Arts' | ||
} | ||
} | ||
}, | ||
'options': { | ||
'proofType': 'Ed25519Signature2018', | ||
'proofPurpose': 'assertionMethod' | ||
} | ||
} | ||
] | ||
|
||
|
||
}) | ||
@IsNotEmpty({ message: 'Please provide valid attributes' }) | ||
@IsArray({ message: 'attributes should be array' }) | ||
@ArrayMaxSize(Number(process.env.OOB_BATCH_SIZE), { message: `Limit reached (${process.env.OOB_BATCH_SIZE} credentials max). Easily handle larger batches via seamless CSV file uploads` }) | ||
|
@@ -229,8 +403,9 @@ export class OOBCredentialDtoWithEmail { | |
@ApiProperty({ example: 'string' }) | ||
@IsNotEmpty({ message: 'Please provide valid credential definition id' }) | ||
@IsString({ message: 'credential definition id should be string' }) | ||
@IsOptional() | ||
@Transform(({ value }) => value.trim()) | ||
credentialDefinitionId: string; | ||
credentialDefinitionId?: string; | ||
|
||
@ApiProperty({ example: 'string' }) | ||
@IsOptional() | ||
|
@@ -244,6 +419,12 @@ export class OOBCredentialDtoWithEmail { | |
@IsString({ message: 'protocol version should be string' }) | ||
protocolVersion?: string; | ||
|
||
@ApiProperty({ example: 'jsonld' }) | ||
@IsNotEmpty({ message: 'Please provide credential type ' }) | ||
@Transform(({ value }) => trim(value).toLocaleLowerCase()) | ||
@IsOptional() | ||
credentialType:IssueCredentialType; | ||
|
||
imageUrl?: string; | ||
|
||
orgId: string; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.