Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement proof presentation for holder #860

Merged
merged 3 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 88 additions & 3 deletions apps/api-gateway/src/cloud-wallet/cloud-wallet.controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IResponse } from '@credebl/common/interfaces/response.interface';
import { ResponseMessages } from '@credebl/common/response-messages';
import { Controller, Post, Logger, Body, HttpStatus, Res, UseFilters, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiForbiddenResponse, ApiOperation, ApiResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger';
import { Controller, Post, Logger, Body, HttpStatus, Res, UseFilters, UseGuards, Get, Param, Query } from '@nestjs/common';
import { ApiBearerAuth, ApiForbiddenResponse, ApiOperation, ApiQuery, ApiResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger';
import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto';
import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto';
import { CloudWalletService } from './cloud-wallet.service';
Expand All @@ -14,6 +14,8 @@ import { AuthGuard } from '@nestjs/passport';
import { User } from '../authz/decorators/user.decorator';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { user } from '@prisma/client';
import { UserRoleGuard } from '../authz/guards/user-role.guard';
import { AcceptProofRequestDto } from './dtos/accept-proof-request.dto';


@UseFilters(CustomExceptionFilter)
Expand Down Expand Up @@ -54,6 +56,86 @@ export class CloudWalletController {
return res.status(HttpStatus.CREATED).json(finalResponse);
}

/**
* Accept proof request
* @param acceptProofRequest
* @param user
* @param res
* @returns sucess message
*/
@Post('/proofs/accept-request')
@ApiOperation({ summary: 'Accept proof request', description: 'Accept proof request' })
@ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto })
@UseGuards(AuthGuard('jwt'), UserRoleGuard)
async acceptProofRequest(
@Res() res: Response,
@Body() acceptProofRequest: AcceptProofRequestDto,
@User() user: user
): Promise<Response> {

const configureBaseWalletData = await this.cloudWalletService.acceptProofRequest(acceptProofRequest, user);
KulkarniShashank marked this conversation as resolved.
Show resolved Hide resolved
const finalResponse: IResponse = {
statusCode: HttpStatus.CREATED,
message: ResponseMessages.cloudWallet.success.acceptProofRequest,
data: configureBaseWalletData
};
return res.status(HttpStatus.CREATED).json(finalResponse);
}

/**
* Get proof presentation by proof id
* @param proofId
* @param res
* @returns sucess message
*/
@Get('/proofs/:proofId')
@ApiOperation({ summary: 'Get proof presentation by Id', description: 'Get proof presentation by Id' })
@ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto })
@UseGuards(AuthGuard('jwt'), UserRoleGuard)
async getProofById(
@Param('proofId') proofId: string,
@Res() res: Response,
@User() user: user
): Promise<Response> {

const getProofDetails = await this.cloudWalletService.getProofById(proofId, user);
const finalResponse: IResponse = {
statusCode: HttpStatus.OK,
message: ResponseMessages.cloudWallet.success.getProofById,
data: getProofDetails
};
return res.status(HttpStatus.OK).json(finalResponse);
}

/**
* Get proof presentations
* @param threadId
* @param res
* @returns sucess message
*/
@Get('/proofs')
@ApiOperation({ summary: 'Get proof presentation', description: 'Get proof presentation' })
@ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto })
@UseGuards(AuthGuard('jwt'), UserRoleGuard)
@ApiQuery({
name: 'threadId',
required: false
})
async getProofPresentation(
@Res() res: Response,
@User() user: user,
@Query('threadId') threadId?: string
): Promise<Response> {

const getProofDetails = await this.cloudWalletService.getProofPresentation(threadId, user);
const finalResponse: IResponse = {
statusCode: HttpStatus.OK,
message: ResponseMessages.cloudWallet.success.getProofPresentation,
data: getProofDetails
};
return res.status(HttpStatus.OK).json(finalResponse);
}

/**
* Create cloud wallet
* @param cloudWalletDetails
Expand All @@ -63,11 +145,14 @@ export class CloudWalletController {
@Post('/create-wallet')
@ApiOperation({ summary: 'Create outbound out-of-band connection invitation', description: 'Create outbound out-of-band connection invitation' })
@ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto })
@UseGuards(AuthGuard('jwt'), UserRoleGuard)
async createCloudWallet(
@Res() res: Response,
@Body() cloudWalletDetails: CreateCloudWalletDto
@Body() cloudWalletDetails: CreateCloudWalletDto,
@User() user: user
): Promise<Response> {

cloudWalletDetails.userId = user.id;
const cloudWalletData = await this.cloudWalletService.createCloudWallet(cloudWalletDetails);
const finalResponse: IResponse = {
statusCode: HttpStatus.CREATED,
Expand Down
25 changes: 25 additions & 0 deletions apps/api-gateway/src/cloud-wallet/cloud-wallet.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ClientProxy } from '@nestjs/microservices';
import { BaseService } from 'libs/service/base.service';
import { CloudBaseWalletConfigureDto } from './dtos/configure-base-wallet.dto';
import { user } from '@prisma/client';
import { AcceptProofRequestDto } from './dtos/accept-proof-request.dto';

@Injectable()
export class CloudWalletService extends BaseService {
Expand All @@ -20,6 +21,30 @@ export class CloudWalletService extends BaseService {
return this.sendNatsMessage(this.cloudWalletServiceProxy, 'configure-cloud-base-wallet', payload);
}

acceptProofRequest(
acceptProofRequest: AcceptProofRequestDto,
user: user
): Promise<object> {
const payload = {acceptProofRequest, user};
return this.sendNatsMessage(this.cloudWalletServiceProxy, 'accept-proof-request-by-holder', payload);
}

getProofById(
proofId: string,
user: user
): Promise<object> {
const payload = {proofId, user};
return this.sendNatsMessage(this.cloudWalletServiceProxy, 'get-proof-by-proof-id-holder', payload);
}

getProofPresentation(
threadId: string,
user: user
): Promise<object> {
const payload = {threadId, user};
return this.sendNatsMessage(this.cloudWalletServiceProxy, 'get-proof-presentation-holder', payload);
}

createCloudWallet(
cloudWalletDetails: ICreateCloudWallet
): Promise<IStoredWalletDetails> {
Expand Down
25 changes: 25 additions & 0 deletions apps/api-gateway/src/cloud-wallet/dtos/accept-proof-request.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsBoolean, IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator';

export class AcceptProofRequestDto {
@ApiProperty({ example: '4e687079-273b-447b-b9dd-9589c84dc6dd' })
@IsString({ message: 'proofRecordId must be a string' })
@IsNotEmpty({ message: 'please provide valid proofRecordId' })
@IsUUID()
proofRecordId: string;

@ApiPropertyOptional({ example: false })
@IsOptional()
@IsBoolean({ message: 'filterByPresentationPreview must be a boolean' })
filterByPresentationPreview?: boolean;

@ApiPropertyOptional({ example: false })
@IsOptional()
@IsBoolean({ message: 'filterByNonRevocationRequirements must be a boolean' })
filterByNonRevocationRequirements?: boolean;

@ApiPropertyOptional({ example: '' })
@IsOptional()
@IsString({ message: 'comment must be a string' })
comment?: string;
}
2 changes: 2 additions & 0 deletions apps/api-gateway/src/cloud-wallet/dtos/cloudWallet.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ export class CreateCloudWalletDto {
@IsNotSQLInjection({ message: 'Image URL is required.' })
connectionImageUrl?: string;

userId: string;

}
22 changes: 22 additions & 0 deletions apps/cloud-wallet/interfaces/cloud-wallet.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,26 @@ export interface IGetStoredWalletInfo {
id: string;
type: $Enums.CloudWalletType;
agentEndpoint: string;
}

export interface IAcceptProofRequest {
proofRecordId: string;
filterByPresentationPreview?: boolean;
filterByNonRevocationRequirements?: boolean;
comment?: string;
}

export interface IAcceptProofRequestPayload {
acceptProofRequest: IAcceptProofRequest
user: user
}

export interface IProofByProofId {
proofId: string
user: user
}

export interface IProofPresentation {
threadId: string
user: user
}
19 changes: 17 additions & 2 deletions apps/cloud-wallet/src/cloud-wallet.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,30 @@ import { Controller } from '@nestjs/common'; // Import the common service in the
import { CloudWalletService } from './cloud-wallet.service'; // Import the common service in connection module
import { MessagePattern } from '@nestjs/microservices'; // Import the nestjs microservices package
import { ICreateCloudWallet, IStoredWalletDetails } from '@credebl/common/interfaces/cloud-wallet.interface';
import { IConfigureCloudBaseWalletPayload, IGetStoredWalletInfo } from '../interfaces/cloud-wallet.interface';
import { IAcceptProofRequestPayload, IConfigureCloudBaseWalletPayload, IGetStoredWalletInfo, IProofByProofId, IProofPresentation } from '../interfaces/cloud-wallet.interface';

@Controller()
export class CloudWalletController {
constructor(private readonly cloudWalletService: CloudWalletService) {}

@MessagePattern({ cmd: 'configure-cloud-base-wallet' })
async configureBaseWallet(payload: IConfigureCloudBaseWalletPayload): Promise<IGetStoredWalletInfo> {
return this.cloudWalletService.configureBaseWallet(payload.cloudBaseWalletConfigure, payload.user);
return this.cloudWalletService.configureBaseWallet(payload.cloudBaseWalletConfigure);
}

@MessagePattern({ cmd: 'accept-proof-request-by-holder' })
async acceptProofRequest(payload: IAcceptProofRequestPayload): Promise<object> {
return this.cloudWalletService.acceptProofRequest(payload.acceptProofRequest, payload.user);
}

@MessagePattern({ cmd: 'get-proof-by-proof-id-holder' })
async getProofById(payload: IProofByProofId): Promise<object> {
return this.cloudWalletService.getProofById(payload.proofId, payload.user);
}

@MessagePattern({ cmd: 'get-proof-presentation-holder' })
async getProofPresentation(payload: IProofPresentation): Promise<object> {
return this.cloudWalletService.getProofPresentation(payload.threadId, payload.user);
}

@MessagePattern({ cmd: 'create-cloud-wallet' })
Expand Down
35 changes: 32 additions & 3 deletions apps/cloud-wallet/src/cloud-wallet.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common';
import { PrismaService } from '@credebl/prisma-service';
import { CloudWalletType } from '@credebl/enum/enum';
// eslint-disable-next-line camelcase
import { cloud_wallet_user_info } from '@prisma/client';
import { cloud_wallet_user_info, user } from '@prisma/client';
import { ICloudWalletDetails, IStoredWalletDetails } from '@credebl/common/interfaces/cloud-wallet.interface';
import { IGetStoredWalletInfo, IStoreWalletInfo } from '../interfaces/cloud-wallet.interface';

Expand Down Expand Up @@ -32,15 +32,15 @@ export class CloudWalletRepository {
// eslint-disable-next-line camelcase
async storeCloudWalletDetails(cloudWalletDetails: ICloudWalletDetails): Promise<IStoredWalletDetails> {
try {
const {createdBy, label, lastChangedBy, tenantId, type, userId, agentApiKey, agentEndpoint, email, key, connectionImageUrl} = cloudWalletDetails;
const {label, lastChangedBy, tenantId, type, userId, agentApiKey, agentEndpoint, email, key, connectionImageUrl} = cloudWalletDetails;

return await this.prisma.cloud_wallet_user_info.create({
data: {
label,
tenantId,
email,
type,
createdBy,
createdBy: userId,
KulkarniShashank marked this conversation as resolved.
Show resolved Hide resolved
lastChangedBy,
userId,
agentEndpoint,
Expand Down Expand Up @@ -107,4 +107,33 @@ export class CloudWalletRepository {
throw error;
}
}

// eslint-disable-next-line camelcase
async getCloudSubWallet(userId: string): Promise<cloud_wallet_user_info> {
try {
const cloudSubWalletDetails = await this.prisma.cloud_wallet_user_info.findFirstOrThrow({
where: {
userId
}
});
return cloudSubWalletDetails;
} catch (error) {
this.logger.error(`Error in getCloudSubWallet: ${error}`);
throw error;
}
}

async getUserInfo(email: string): Promise<user> {
try {
const userDetails = await this.prisma.user.findUnique({
where: {
email
}
});
return userDetails;
} catch (error) {
this.logger.error(`Error in getUserInfo: ${error}`);
throw error;
}
}
}
Loading