Skip to content

Commit

Permalink
Merge pull request #147 from hypersign-protocol/implement/didAuth
Browse files Browse the repository at this point in the history
added api for sign and verify didDocument
  • Loading branch information
Vishwas1 authored Sep 19, 2024
2 parents 6e856a6 + 0e5f48b commit ab64e8e
Show file tree
Hide file tree
Showing 4 changed files with 462 additions and 5 deletions.
69 changes: 66 additions & 3 deletions src/did/controllers/did.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ import { RegisterDidDto } from '../dto/register-did.dto';
import { IKeyType } from 'hs-ssi-sdk';
import { AtLeastOneParamPipe } from 'src/utils/Pipes/atleastOneParam.pipe';
import { AddVMResponse, AddVerificationMethodDto } from '../dto/addVm.dto';
import { SignDidDto, SignedDidDocument } from '../dto/sign-did.dto';
import { VerifyDidDocResponseDto, VerifyDidDto } from '../dto/verify-did.dto';
@UseFilters(AllExceptionsFilter)
@ApiTags('Did')
@Controller('did')
Expand Down Expand Up @@ -192,7 +194,7 @@ export class DidController {
}

@Post('/addVerificationMethod')
@ApiCreatedResponse({
@ApiOkResponse({
description: 'Added vm to Did Document',
type: AddVMResponse,
})
Expand All @@ -217,12 +219,73 @@ export class DidController {
addVerficationMethod(
@Headers('Authorization') authorization: string,
@Body() addVm: AddVerificationMethodDto,
@Req() req: any,
) {
Logger.log('addVerificationMethod() method: starts', 'DidController');
return this.didService.addVerificationMethod(addVm);
}
@ApiCreatedResponse({

@Post('/sign')
@ApiOkResponse({
description: 'DidDocument is signed successfully',
type: SignedDidDocument,
})
@ApiBadRequestResponse({
status: 400,
description: 'Error occured at the time of signing did',
type: DidError,
})
@ApiHeader({
name: 'Authorization',
description: 'Bearer <access_token>',
required: false,
})
@ApiHeader({
name: 'Origin',
description: 'Origin as you set in application cors',
required: false,
})
@UsePipes(ValidationPipe)
@UsePipes(new AtLeastOneParamPipe(['did', 'didDocument']))
SignDidDocument(
@Headers('Authorization') authorization: string,
@Req() req: any,
@Body() signDidDocDto: SignDidDto,
) {
Logger.log('SignDidDocument() method: starts', 'DidController');
return this.didService.SignDidDocument(signDidDocDto, req.user);
}
@Post('/verify')
@ApiOkResponse({
description: 'DidDocument is verified successfully',
type: VerifyDidDocResponseDto,
})
@ApiBadRequestResponse({
status: 400,
description: 'Error occured at the time of verifing did',
type: DidError,
})
@ApiHeader({
name: 'Authorization',
description: 'Bearer <access_token>',
required: false,
})
@ApiHeader({
name: 'Origin',
description: 'Origin as you set in application cors',
required: false,
})
@UsePipes(ValidationPipe)
@UsePipes(new AtLeastOneParamPipe(['did', 'didDocument']))
VerifyDidDocument(
@Headers('Authorization') authorization: string,
@Req() req: any,
@Body() verifyDidDto: VerifyDidDto,
) {
Logger.log('VerifyDidDocument() method: starts', 'DidController');
return this.didService.VerifyDidDocument(verifyDidDto, req.user);
}

@ApiOkResponse({
description: 'DID Registred',
type: RegisterDidResponse,
})
Expand Down
157 changes: 157 additions & 0 deletions src/did/dto/sign-did.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import { ApiProperty } from '@nestjs/swagger';
import { DidDoc } from './update-did.dto';
import {
IsEnum,
IsNotEmptyObject,
IsOptional,
IsString,
Matches,
ValidateIf,
ValidateNested,
} from 'class-validator';
import { Type } from 'class-transformer';
import { ValidateVerificationMethodId } from 'src/utils/customDecorator/vmId.decorator';
import { IsDid } from 'src/utils/customDecorator/did.decorator';
import { SupportedPurpose } from 'hs-ssi-sdk';

export enum Purpose {
'assertion' = 'assertion',
'authentication' = 'authentication',
}
export class Proof {
@ApiProperty({
name: 'type',
description: 'signature type',
example: 'Ed25519Signature2020',
})
@IsString()
type: string;
@ApiProperty({
name: 'created',
description: 'Time at which documant is signed',
example: '2024-05-10T08:29:15Z',
})
@IsString()
created: string;
@ApiProperty({
name: 'verificationMethod',
description: 'verificationMethodId which is used for signing',
example:
'did:hid:testnet:z6MkvfkK24wE6KxJbw6XadDkmMSZwhmtJx4mYZG6hFci9eNm#key-1',
})
@IsString()
@ValidateVerificationMethodId()
verificationMethod: string;
@ApiProperty({
name: 'proofPurpose',
description: 'proofPurpose',
example: SupportedPurpose.authentication,
})
@IsString()
proofPurpose: string;
@ApiProperty({
name: 'challenge',
description:
'Random string used to sign in required in case of purpose authentication',
example: 'skfdhldklgjh-gaghkdhgaskda-aisgkjheyi',
})
@ValidateIf((o) => o.purpose === 'authentication')
@IsString()
challenge?: string;
@ApiProperty({
name: 'domain',
description: 'domain',
example: 'example.com',
})
@ValidateIf((o) => o.purpose === 'authentication')
@IsString()
domain?: string;

@ApiProperty({
name: 'proofValue',
description: 'proofValue of the didDocument',
example:
'z4CQEX1xAHauoMbAXfP3igFoKfPAETrGc3FwC5CAtnnLLZEX9FwghJ1eashf9zANfnNPYLZVyhGVg4m43Q9fs',
})
@IsString()
proofValue: string;
}

export class SignedDidDocument extends DidDoc {
@ApiProperty({
name: 'proof',
description: 'proof object of didDocument',
type: Proof,
})
proof: Proof;
}

export class BaseDidDto {
@ApiProperty({
name: 'didDocument',
description: 'didDocument',
type: DidDoc,
})
didDocument: any;
@ApiProperty({
description: 'Verification Method id for did registration',
example: 'did:hid:testnet:........#key-${idx}',
required: true,
})
@ValidateVerificationMethodId()
@IsString()
@Matches(/^[a-zA-Z0-9\:]*testnet[a-zA-Z0-9\-:#]*$/, {
message: "Did's namespace should be testnet",
}) // this is to validate if did is generated using empty namespace
verificationMethodId: string;
@ApiProperty({
name: 'purpose',
description: 'purpose for signing didDocument',
example: 'authentication',
required: false,
})
@IsString()
@IsEnum(SupportedPurpose)
purpose: SupportedPurpose;
@ApiProperty({
name: 'challenge',
description:
'Random string used to sign in required in case of purpose authentication',
example: 'skfdhldklgjh-gaghkdhgaskda-aisgkjheyi',
required: false,
})
@ValidateIf((o) => o.purpose === 'authentication')
@IsString()
challenge: string;
@ApiProperty({
name: 'domain',
description: 'domain',
example: 'example.com',
required: false,
})
@ValidateIf((o) => o.purpose === 'authentication')
@IsString()
domain: string;
}

export class SignDidDto extends BaseDidDto {
@ApiProperty({
name: 'didDocument',
description: 'didDocument',
type: DidDoc,
})
@IsOptional()
@IsNotEmptyObject()
@Type(() => DidDoc)
@ValidateNested({ each: true })
didDocument: DidDoc;
@ApiProperty({
name: 'did',
description: 'Id of the didDocument',
example: 'did:hid:testnet:........',
})
@IsOptional()
@IsDid()
@IsString()
did: string;
}
Loading

0 comments on commit ab64e8e

Please sign in to comment.