diff --git a/apps/api-gateway/src/cloud-wallet/cloud-wallet.controller.ts b/apps/api-gateway/src/cloud-wallet/cloud-wallet.controller.ts index c0ad7482c..e7a7c188d 100644 --- a/apps/api-gateway/src/cloud-wallet/cloud-wallet.controller.ts +++ b/apps/api-gateway/src/cloud-wallet/cloud-wallet.controller.ts @@ -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'; @@ -14,6 +14,9 @@ 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'; +import { IGetProofPresentation, IGetProofPresentationById } from '@credebl/common/interfaces/cloud-wallet.interface'; @UseFilters(CustomExceptionFilter) @@ -45,7 +48,12 @@ export class CloudWalletController { @User() user: user ): Promise { - const configureBaseWalletData = await this.cloudWalletService.configureBaseWallet(cloudBaseWalletConfigure, user); + const { id, email } = user; + + cloudBaseWalletConfigure.userId = id; + cloudBaseWalletConfigure.email = email; + + const configureBaseWalletData = await this.cloudWalletService.configureBaseWallet(cloudBaseWalletConfigure); const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.cloudWallet.success.configureBaseWallet, @@ -54,6 +62,104 @@ 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 { + const { id, email } = user; + acceptProofRequest.userId = id; + acceptProofRequest.email = email; + + const acceptProofRequestDetails = await this.cloudWalletService.acceptProofRequest(acceptProofRequest); + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.cloudWallet.success.acceptProofRequest, + data: acceptProofRequestDetails + }; + return res.status(HttpStatus.CREATED).json(finalResponse); + } + + /** + * Get proof presentation by proof id + * @param proofRecordId + * @param res + * @returns sucess message + */ + @Get('/proofs/:proofRecordId') + @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('proofRecordId') proofRecordId: string, + @Res() res: Response, + @User() user: user + ): Promise { + const { id, email } = user; + + const proofPresentationByIdPayload: IGetProofPresentationById = { + userId: id, + email, + proofRecordId + }; + + const getProofDetails = await this.cloudWalletService.getProofById(proofPresentationByIdPayload); + 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 { + + const { id, email } = user; + + const proofPresentationPayload: IGetProofPresentation = { + userId: id, + email, + threadId + }; + + const getProofDetails = await this.cloudWalletService.getProofPresentation(proofPresentationPayload); + 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 diff --git a/apps/api-gateway/src/cloud-wallet/cloud-wallet.service.ts b/apps/api-gateway/src/cloud-wallet/cloud-wallet.service.ts index 211284155..e66cb7033 100644 --- a/apps/api-gateway/src/cloud-wallet/cloud-wallet.service.ts +++ b/apps/api-gateway/src/cloud-wallet/cloud-wallet.service.ts @@ -1,10 +1,8 @@ -import { ICreateCloudWallet, IGetStoredWalletInfo, IStoredWalletDetails } from '@credebl/common/interfaces/cloud-wallet.interface'; +import { IAcceptProofRequest, IProofRequestRes, ICloudBaseWalletConfigure, ICreateCloudWallet, IGetProofPresentation, IGetProofPresentationById, IGetStoredWalletInfo, IStoredWalletDetails } from '@credebl/common/interfaces/cloud-wallet.interface'; import { Inject, Injectable} from '@nestjs/common'; 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'; @Injectable() export class CloudWalletService extends BaseService { @@ -13,11 +11,27 @@ export class CloudWalletService extends BaseService { } configureBaseWallet( - cloudBaseWalletConfigure: CloudBaseWalletConfigureDto, - user: user + cloudBaseWalletConfigure: ICloudBaseWalletConfigure ): Promise { - const payload = {cloudBaseWalletConfigure, user}; - return this.sendNatsMessage(this.cloudWalletServiceProxy, 'configure-cloud-base-wallet', payload); + return this.sendNatsMessage(this.cloudWalletServiceProxy, 'configure-cloud-base-wallet', cloudBaseWalletConfigure); + } + + acceptProofRequest( + acceptProofRequest: IAcceptProofRequest + ): Promise { + return this.sendNatsMessage(this.cloudWalletServiceProxy, 'accept-proof-request-by-holder', acceptProofRequest); + } + + getProofById( + proofPresentationByIdPayload: IGetProofPresentationById + ): Promise { + return this.sendNatsMessage(this.cloudWalletServiceProxy, 'get-proof-by-proof-id-holder', proofPresentationByIdPayload); + } + + getProofPresentation( + proofPresentationPayload: IGetProofPresentation + ): Promise { + return this.sendNatsMessage(this.cloudWalletServiceProxy, 'get-proof-presentation-holder', proofPresentationPayload); } createCloudWallet( diff --git a/apps/api-gateway/src/cloud-wallet/dtos/accept-proof-request.dto.ts b/apps/api-gateway/src/cloud-wallet/dtos/accept-proof-request.dto.ts new file mode 100644 index 000000000..291639217 --- /dev/null +++ b/apps/api-gateway/src/cloud-wallet/dtos/accept-proof-request.dto.ts @@ -0,0 +1,29 @@ +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; + + userId: string; + + email: string; +} diff --git a/apps/api-gateway/src/cloud-wallet/dtos/cloudWallet.dto.ts b/apps/api-gateway/src/cloud-wallet/dtos/cloudWallet.dto.ts index d5683cfb2..f6fc97e62 100644 --- a/apps/api-gateway/src/cloud-wallet/dtos/cloudWallet.dto.ts +++ b/apps/api-gateway/src/cloud-wallet/dtos/cloudWallet.dto.ts @@ -16,5 +16,4 @@ export class CreateCloudWalletDto { @IsNotEmpty({ message: 'please provide valid image URL' }) @IsNotSQLInjection({ message: 'Image URL is required.' }) connectionImageUrl?: string; - } diff --git a/apps/api-gateway/src/cloud-wallet/dtos/configure-base-wallet.dto.ts b/apps/api-gateway/src/cloud-wallet/dtos/configure-base-wallet.dto.ts index 1518843c9..47d89271b 100644 --- a/apps/api-gateway/src/cloud-wallet/dtos/configure-base-wallet.dto.ts +++ b/apps/api-gateway/src/cloud-wallet/dtos/configure-base-wallet.dto.ts @@ -1,17 +1,9 @@ -import { IsEmail, IsNotEmpty, IsString } from 'class-validator'; +import { IsNotEmpty, IsString } from 'class-validator'; import { ApiProperty } from '@nestjs/swagger'; -import { IsHostPortOrDomain, trim } from '@credebl/common/cast.helper'; -import { Transform } from 'class-transformer'; +import { IsHostPortOrDomain } from '@credebl/common/cast.helper'; export class CloudBaseWalletConfigureDto { - @ApiProperty({ example: 'awqx@getnada.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - email: string; - @ApiProperty({ example: 'xxx-xxxx-xxxx' }) @IsString({ message: 'walletKey must be a string' }) @IsNotEmpty({ message: 'please provide valid walletKey' }) @@ -27,4 +19,8 @@ export class CloudBaseWalletConfigureDto { @IsNotEmpty({ message: 'please provide valid agentEndpoint' }) @IsHostPortOrDomain({ message: 'agentEndpoint must be a valid host:port or domain' }) agentEndpoint: string; + + userId: string; + + email: string; } diff --git a/apps/cloud-wallet/interfaces/cloud-wallet.interface.ts b/apps/cloud-wallet/interfaces/cloud-wallet.interface.ts deleted file mode 100644 index 593d9f028..000000000 --- a/apps/cloud-wallet/interfaces/cloud-wallet.interface.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { CloudWalletType } from '@credebl/enum/enum'; -import { $Enums, user } from '@prisma/client'; - -export interface IConfigureCloudBaseWallet { - email: string; - walletKey: string; - apiKey: string; - agentEndpoint: string; -} - -export interface IConfigureCloudBaseWalletPayload { - cloudBaseWalletConfigure: IConfigureCloudBaseWallet, - user: user -} - -export interface IStoreWalletInfo { - email: string; - walletKey: string; - apiKey: string; - agentEndpoint: string; - type: CloudWalletType; - userId: string; -} - -export interface IGetStoredWalletInfo { - email: string; - userId: string; - id: string; - type: $Enums.CloudWalletType; - agentEndpoint: string; -} \ No newline at end of file diff --git a/apps/cloud-wallet/src/cloud-wallet.controller.ts b/apps/cloud-wallet/src/cloud-wallet.controller.ts index 7e1faa2a2..b08df453d 100644 --- a/apps/cloud-wallet/src/cloud-wallet.controller.ts +++ b/apps/cloud-wallet/src/cloud-wallet.controller.ts @@ -2,16 +2,30 @@ import { Controller } from '@nestjs/common'; // Import the common service in the library 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 { IAcceptProofRequest, IProofRequestRes, ICloudBaseWalletConfigure, ICreateCloudWallet, IGetProofPresentation, IGetProofPresentationById, IGetStoredWalletInfo, IStoredWalletDetails } from '@credebl/common/interfaces/cloud-wallet.interface'; @Controller() export class CloudWalletController { constructor(private readonly cloudWalletService: CloudWalletService) {} @MessagePattern({ cmd: 'configure-cloud-base-wallet' }) - async configureBaseWallet(payload: IConfigureCloudBaseWalletPayload): Promise { - return this.cloudWalletService.configureBaseWallet(payload.cloudBaseWalletConfigure, payload.user); + async configureBaseWallet(configureBaseWalletPayload: ICloudBaseWalletConfigure): Promise { + return this.cloudWalletService.configureBaseWallet(configureBaseWalletPayload); + } + + @MessagePattern({ cmd: 'accept-proof-request-by-holder' }) + async acceptProofRequest(acceptProofRequestPayload: IAcceptProofRequest): Promise { + return this.cloudWalletService.acceptProofRequest(acceptProofRequestPayload); + } + + @MessagePattern({ cmd: 'get-proof-by-proof-id-holder' }) + async getProofById(proofPrsentationByIdPayload: IGetProofPresentationById): Promise { + return this.cloudWalletService.getProofById(proofPrsentationByIdPayload); + } + + @MessagePattern({ cmd: 'get-proof-presentation-holder' }) + async getProofPresentation(proofPresentationPayload: IGetProofPresentation): Promise { + return this.cloudWalletService.getProofPresentation(proofPresentationPayload); } @MessagePattern({ cmd: 'create-cloud-wallet' }) diff --git a/apps/cloud-wallet/src/cloud-wallet.repository.ts b/apps/cloud-wallet/src/cloud-wallet.repository.ts index 13f260a96..f5244e21d 100644 --- a/apps/cloud-wallet/src/cloud-wallet.repository.ts +++ b/apps/cloud-wallet/src/cloud-wallet.repository.ts @@ -2,9 +2,8 @@ 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 { ICloudWalletDetails, IStoredWalletDetails } from '@credebl/common/interfaces/cloud-wallet.interface'; -import { IGetStoredWalletInfo, IStoreWalletInfo } from '../interfaces/cloud-wallet.interface'; +import { cloud_wallet_user_info, user } from '@prisma/client'; +import { ICloudWalletDetails, IGetStoredWalletInfo, IStoredWalletDetails, IStoreWalletInfo } from '@credebl/common/interfaces/cloud-wallet.interface'; @Injectable() @@ -32,7 +31,7 @@ export class CloudWalletRepository { // eslint-disable-next-line camelcase async storeCloudWalletDetails(cloudWalletDetails: ICloudWalletDetails): Promise { 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: { @@ -40,7 +39,7 @@ export class CloudWalletRepository { tenantId, email, type, - createdBy, + createdBy: userId, lastChangedBy, userId, agentEndpoint, @@ -82,16 +81,17 @@ export class CloudWalletRepository { async storeCloudWalletInfo(cloudWalletInfoPayload: IStoreWalletInfo): Promise { try { + const { agentEndpoint, agentApiKey, email, type, userId, key, createdBy, lastChangedBy } = cloudWalletInfoPayload; const walletInfoData = await this.prisma.cloud_wallet_user_info.create({ data: { - type: cloudWalletInfoPayload.type, - agentApiKey: cloudWalletInfoPayload.apiKey, - agentEndpoint: cloudWalletInfoPayload.agentEndpoint, - email: cloudWalletInfoPayload.email, - userId: cloudWalletInfoPayload.userId, - key: cloudWalletInfoPayload.walletKey, - createdBy: cloudWalletInfoPayload.userId, - lastChangedBy: cloudWalletInfoPayload.userId + type, + agentApiKey, + agentEndpoint, + email, + userId, + key, + createdBy, + lastChangedBy }, select: { id: true, @@ -107,4 +107,33 @@ export class CloudWalletRepository { throw error; } } + + // eslint-disable-next-line camelcase + async getCloudSubWallet(userId: string): Promise { + 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 { + try { + const userDetails = await this.prisma.user.findUnique({ + where: { + email + } + }); + return userDetails; + } catch (error) { + this.logger.error(`Error in getUserInfo: ${error}`); + throw error; + } + } } diff --git a/apps/cloud-wallet/src/cloud-wallet.service.ts b/apps/cloud-wallet/src/cloud-wallet.service.ts index 8214920b9..d51836226 100644 --- a/apps/cloud-wallet/src/cloud-wallet.service.ts +++ b/apps/cloud-wallet/src/cloud-wallet.service.ts @@ -4,13 +4,11 @@ import { BadRequestException, ConflictException, Inject, Injectable, InternalSer import { ClientProxy } from '@nestjs/microservices'; import { Cache } from 'cache-manager'; import { CACHE_MANAGER } from '@nestjs/cache-manager'; -import { ICloudWalletDetails, ICreateCloudWallet, IStoredWalletDetails } from '@credebl/common/interfaces/cloud-wallet.interface'; +import { IAcceptProofRequest, IProofRequestRes, ICloudBaseWalletConfigure, ICloudWalletDetails, ICreateCloudWallet, IGetProofPresentation, IGetProofPresentationById, IGetStoredWalletInfo, IStoredWalletDetails, CloudWallet, IStoreWalletInfo } from '@credebl/common/interfaces/cloud-wallet.interface'; import { CloudWalletRepository } from './cloud-wallet.repository'; import { ResponseMessages } from '@credebl/common/response-messages'; import { CloudWalletType } from '@credebl/enum/enum'; import { CommonConstants } from '@credebl/common/common.constant'; -import { IConfigureCloudBaseWallet, IGetStoredWalletInfo } from '../interfaces/cloud-wallet.interface'; -import { user } from '@prisma/client'; @Injectable() export class CloudWalletService { @@ -22,12 +20,17 @@ export class CloudWalletService { @Inject(CACHE_MANAGER) private cacheService: Cache ) {} - async configureBaseWallet(cloudBaseWalletConfigure: IConfigureCloudBaseWallet, user: user): Promise { - const { agentEndpoint, apiKey, email, walletKey } = cloudBaseWalletConfigure; + /** + * configure cloud base wallet + * @param configureBaseWalletPayload + * @returns cloud base wallet + */ + async configureBaseWallet(configureBaseWalletPayload: ICloudBaseWalletConfigure): Promise { + const { agentEndpoint, apiKey, email, walletKey, userId } = configureBaseWalletPayload; try { - const getAgentDetails = await this.commonService.httpGet(`${agentEndpoint}${CommonConstants.URL_AGENT_GET_ENDPOINT}`); - if (!getAgentDetails?.isInitialized) { + const getAgentInfo = await this.commonService.httpGet(`${agentEndpoint}${CommonConstants.URL_AGENT_GET_ENDPOINT}`); + if (!getAgentInfo?.isInitialized) { throw new BadRequestException(ResponseMessages.cloudWallet.error.notReachable); } @@ -41,13 +44,15 @@ export class CloudWalletService { this.commonService.dataEncryption(apiKey) ]); - const walletInfoToStore = { + const walletInfoToStore: IStoreWalletInfo = { agentEndpoint, - apiKey: encryptionApiKey, + agentApiKey: encryptionApiKey, email, type: CloudWalletType.BASE_WALLET, - userId: user.id, - walletKey: encryptionWalletKey + userId, + key: encryptionWalletKey, + createdBy: userId, + lastChangedBy: userId }; const storedWalletInfo = await this.cloudWalletRepository.storeCloudWalletInfo(walletInfoToStore); @@ -58,6 +63,110 @@ export class CloudWalletService { } } + /** + * Accept proof request + * @param acceptProofRequest + * @returns proof presentation + */ + async acceptProofRequest(acceptProofRequest: IAcceptProofRequest): Promise { + const { proofRecordId, comment, filterByNonRevocationRequirements, filterByPresentationPreview, userId } = acceptProofRequest; + try { + + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + + const { tenantId } = getTenant; + const { agentEndpoint } = baseWalletDetails; + + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_GET_PROOF_REQUEST}/${proofRecordId}${CommonConstants.CLOUD_WALLET_ACCEPT_PROOF_REQUEST}${tenantId}`; + const proofAcceptRequestPayload = { + comment, + filterByNonRevocationRequirements, + filterByPresentationPreview + }; + + + const acceptProofRequest = await this.commonService.httpPost(url, proofAcceptRequestPayload, { headers: { authorization: decryptedApiKey } }); + return acceptProofRequest; + } catch (error) { + await this.commonService.handleError(error); + throw error; + } + } + + /** + * Get proof presentation by proof Id + * @param proofPrsentationByIdPayload + * @returns proof presentation + */ + async getProofById(proofPrsentationByIdPayload: IGetProofPresentationById): Promise { + try { + const { proofRecordId, userId } = proofPrsentationByIdPayload; + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + + const { tenantId } = getTenant; + const { agentEndpoint } = baseWalletDetails; + + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_GET_PROOF_REQUEST}/${proofRecordId}/${tenantId}`; + + const getProofById = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }); + return getProofById; + } catch (error) { + await this.commonService.handleError(error); + throw error; + } + } + + /** + * Get proof presentation + * @param proofPresentationPayload + * @returns proof presentations + */ + async getProofPresentation(proofPresentationPayload: IGetProofPresentation): Promise { + try { + const { threadId, userId } = proofPresentationPayload; + + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + + const { tenantId } = getTenant; + const { agentEndpoint } = baseWalletDetails; + + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_GET_PROOF_REQUEST}/${tenantId}${threadId ? `?threadId=${threadId}` : ''}`; + + const getProofById = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }); + return getProofById; + } catch (error) { + await this.commonService.handleError(error); + throw error; + } + } + + /** + * common function for get cloud wallet + * @param userId + * @returns cloud wallet info + */ + async _commonCloudWalletInfo(userId: string): Promise<[CloudWallet, CloudWallet, unknown]> { + const baseWalletDetails = await this.cloudWalletRepository.getCloudWalletDetails(CloudWalletType.BASE_WALLET); + + if (!baseWalletDetails) { + throw new NotFoundException(ResponseMessages.cloudWallet.error.notFoundBaseWallet); + } + + const getAgentDetails = await this.commonService.httpGet(`${baseWalletDetails?.agentEndpoint}${CommonConstants.URL_AGENT_GET_ENDPOINT}`); + if (!getAgentDetails?.isInitialized) { + throw new BadRequestException(ResponseMessages.cloudWallet.error.notReachable); + } + + const getTenant = await this.cloudWalletRepository.getCloudSubWallet(userId); + + if (!getTenant) { + throw new NotFoundException(ResponseMessages.cloudWallet.error.walletRecordNotFound); + } + + const decryptedApiKey = await this.commonService.decryptPassword(getTenant?.agentApiKey); + + return [baseWalletDetails, getTenant, decryptedApiKey]; + } /** * Create clous wallet diff --git a/libs/common/src/common.constant.ts b/libs/common/src/common.constant.ts index 714b6a768..eee9387f2 100644 --- a/libs/common/src/common.constant.ts +++ b/libs/common/src/common.constant.ts @@ -119,6 +119,8 @@ export enum CommonConstants { URL_SHAGENT_SEND_ANSWER = '/multi-tenancy/question-answer/answer/#/@', URL_SHAGENT_QUESTION_ANSWER_RECORD = '/multi-tenancy/question-answer/#', URL_SHAGENT_DELETE_SUB_WALLET = '/multi-tenancy/#', + URL_SHAGENT_ACCEPT_PROOF_REQUEST = '/multi-tenancy/proofs/#/accept-request/@', + // PROOF SERVICES URL_SEND_PROOF_REQUEST = '/proofs/request-proof', @@ -328,6 +330,9 @@ CACHE_SHARED_APIKEY_KEY = "dedicatedApiKey", CACHE_APIKEY_KEY = "sharedApiKey", CACHE_TTL_SECONDS = 604800, +CLOUD_WALLET_GET_PROOF_REQUEST = '/multi-tenancy/proofs', +CLOUD_WALLET_ACCEPT_PROOF_REQUEST = '/accept-request/', + // Bulk-issuance BATCH_SIZE = 100, MAX_CONCURRENT_OPERATIONS = 50, diff --git a/libs/common/src/interfaces/cloud-wallet.interface.ts b/libs/common/src/interfaces/cloud-wallet.interface.ts index 7e30e0ab7..4de615d05 100644 --- a/libs/common/src/interfaces/cloud-wallet.interface.ts +++ b/libs/common/src/interfaces/cloud-wallet.interface.ts @@ -38,4 +38,116 @@ export interface IGetStoredWalletInfo { id: string; type: $Enums.CloudWalletType; agentEndpoint: string; +} + +export interface IConfigureCloudBaseWallet { + email: string; + walletKey: string; + apiKey: string; + agentEndpoint: string; +} + +export interface IConfigureCloudBaseWalletPayload { + cloudBaseWalletConfigure: IConfigureCloudBaseWallet; + userId: string; +} + +export interface IStoreWalletInfo { + email: string; + key: string; + agentApiKey: string; + agentEndpoint: string; + type: CloudWalletType; + userId: string; + createdBy: string; + lastChangedBy: string +} + +export interface IGetStoredWalletInfo { + email: string; + userId: string; + id: string; + type: $Enums.CloudWalletType; + agentEndpoint: string; +} + +export interface IAcceptProofRequest { + proofRecordId: string; + userId: string; + email: string; + filterByPresentationPreview?: boolean; + filterByNonRevocationRequirements?: boolean; + comment?: string; +} + +export interface IAcceptProofRequestPayload { + acceptProofRequest: IAcceptProofRequest; + userId: string; +} + +export interface IProofByProofId { + proofId: string; + userId: string; +} + +export interface IProofPresentation { + threadId: string; + userId: string; +} + +export interface IGetProofPresentationById { + userId: string; + email: string; + proofRecordId: string; +} + +export interface IGetProofPresentation { + userId: string; + email: string; + threadId: string; +} + +export interface ICloudBaseWalletConfigure { + walletKey: string; + apiKey: string; + agentEndpoint: string; + userId: string; + email: string; +} + +export interface Tags { + connectionId: string; + role: string; + state: string; + threadId: string; +} + +export interface IProofRequestRes { + _tags: Tags; + metadata: unknown; + id: string; + createdAt: string; + protocolVersion: string; + state: string; + role: string; + connectionId: string; + threadId: string; + updatedAt: string; +} + +export interface CloudWallet { + id: string; + label: string; + tenantId: string; + email: string; + type: $Enums.CloudWalletType; + createDateTime: Date; + createdBy: string; + lastChangedDateTime: Date; + lastChangedBy: string; + userId: string; + agentEndpoint: string; + agentApiKey: string; + key: string; + connectionImageUrl: string; } \ No newline at end of file diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index aa45cadd5..577cb7c99 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -518,14 +518,20 @@ export const ResponseMessages = { cloudWallet: { success: { create: 'Cloud wallet created successfully', - configureBaseWallet: 'Successfully configure the base wallet.' + configureBaseWallet: 'Successfully configure the base wallet.', + acceptProofRequest: 'Proof request has been successfully accepted.', + getProofById: 'Proof presentation has been successfully received.', + getProofPresentation: 'Proof presentations has been successfully received.' }, error: { baseWalletNotFound: 'Base wallet configuration not found', createCloudWallet: 'Error while creating cloud wallet on agent', encryptCloudWalletKey: 'Error while creating encrypting wallet key', notReachable: 'The agent endpoint is not reachable.', - agentAlreadyExist: 'Agent already exist.' + agentAlreadyExist: 'Agent already exist.', + platformAdminRecordNotFound: 'Platform admin reocrd not exist.', + notFoundBaseWallet: 'The base wallet record is missing.', + walletRecordNotFound: 'Wallet record not found.' } } };