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: Pagination and sorting for connections, issuance, and verification #343

Merged
merged 14 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
71 changes: 39 additions & 32 deletions apps/api-gateway/src/connection/connection.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import IResponseType from '@credebl/common/interfaces/response.interface';
import { ResponseMessages } from '@credebl/common/response-messages';
import { Controller, Logger, Post, Body, UseGuards, HttpStatus, Res, Get, Param, Query, UseFilters } from '@nestjs/common';
import { Controller, Logger, Post, Body, UseGuards, HttpStatus, Res, Get, Param, UseFilters, Query } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiExcludeEndpoint, ApiForbiddenResponse, ApiOperation, ApiQuery, ApiResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger';
import { User } from '../authz/decorators/user.decorator';
Expand All @@ -11,12 +11,13 @@ import { ConnectionService } from './connection.service';
import { ConnectionDto, CreateConnectionDto } from './dtos/connection.dto';
import { IUserRequestInterface } from './interfaces';
import { Response } from 'express';
import { Connections } from './enums/connections.enum';
import { IUserRequest } from '@credebl/user-request/user-request.interface';
import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler';
import { OrgRoles } from 'libs/org-roles/enums';
import { Roles } from '../authz/decorators/roles.decorator';
import { OrgRolesGuard } from '../authz/guards/org-roles.guard';
import { GetAllConnectionsDto } from './dtos/get-all-connections.dto';
import { IConnectionSearchinterface } from '../interfaces/ISchemaSearch.interface';

@UseFilters(CustomExceptionFilter)
@Controller()
Expand Down Expand Up @@ -64,9 +65,6 @@ export class ConnectionController {
/**
* Description: Get all connections
* @param user
* @param threadId
* @param connectionId
* @param state
* @param orgId
*
*/
Expand All @@ -77,40 +75,48 @@ export class ConnectionController {
summary: `Fetch all connection details`,
description: `Fetch all connection details`
})
@ApiQuery({
name: 'pageNumber',
type: Number,
required: false
})
@ApiQuery({
name: 'searchByText',
type: String,
required: false
})
@ApiQuery({
name: 'pageSize',
type: Number,
required: false
})
@ApiQuery({
name: 'sorting',
type: String,
required: false
})
@ApiQuery({
name: 'sortByValue',
type: String,
required: false
})
@ApiResponse({ status: 200, description: 'Success', type: AuthTokenResponse })
@ApiQuery(
{ name: 'outOfBandId', required: false }
)
@ApiQuery(
{ name: 'alias', required: false }
)
@ApiQuery(
{ name: 'state', enum: Connections, required: false }
)
@ApiQuery(
{ name: 'myDid', required: false }
)
@ApiQuery(
{ name: 'theirDid', required: false }
)
@ApiQuery(
{ name: 'theirLabel', required: false }
)
async getConnections(
@Query() getAllConnectionsDto: GetAllConnectionsDto,
@User() user: IUserRequest,
@Query('outOfBandId') outOfBandId: string,
@Query('alias') alias: string,
@Query('state') state: string,
@Query('myDid') myDid: string,
@Query('theirDid') theirDid: string,
@Query('theirLabel') theirLabel: string,
@Param('orgId') orgId: string,
@Res() res: Response
): Promise<Response> {

// eslint-disable-next-line no-param-reassign
state = state || undefined;
const connectionDetails = await this.connectionService.getConnections(user, outOfBandId, alias, state, myDid, theirDid, theirLabel, orgId);
const { pageSize, searchByText, pageNumber, sorting, sortByValue } = getAllConnectionsDto;
const connectionSearchCriteria: IConnectionSearchinterface = {
pageNumber,
searchByText,
pageSize,
sorting,
sortByValue
};
const connectionDetails = await this.connectionService.getConnections(connectionSearchCriteria, user, orgId);

const finalResponse: IResponseType = {
statusCode: HttpStatus.OK,
Expand Down Expand Up @@ -149,6 +155,7 @@ export class ConnectionController {

}


/**
* Catch connection webhook responses.
* @Body connectionDto
Expand Down
109 changes: 63 additions & 46 deletions apps/api-gateway/src/connection/connection.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,77 @@ import { ClientProxy, RpcException } from '@nestjs/microservices';
import { BaseService } from 'libs/service/base.service';
import { ConnectionDto, CreateConnectionDto } from './dtos/connection.dto';
import { IUserRequestInterface } from './interfaces';

import { IConnectionSearchinterface } from '../interfaces/ISchemaSearch.interface';

@Injectable()
export class ConnectionService extends BaseService {
constructor(
@Inject('NATS_CLIENT') private readonly connectionServiceProxy: ClientProxy
) {
super('ConnectionService');
}
constructor(@Inject('NATS_CLIENT') private readonly connectionServiceProxy: ClientProxy) {
super('ConnectionService');
}

createLegacyConnectionInvitation(connectionDto: CreateConnectionDto, user: IUserRequestInterface): Promise<{
response: object;
}> {
try {

const connectionDetails = { orgId: connectionDto.orgId, alias: connectionDto.alias, label: connectionDto.label, imageUrl: connectionDto.imageUrl, multiUseInvitation: connectionDto.multiUseInvitation, autoAcceptConnection: connectionDto.autoAcceptConnection, user };
createLegacyConnectionInvitation(
connectionDto: CreateConnectionDto,
user: IUserRequestInterface
): Promise<{
response: object;
}> {
try {
const connectionDetails = {
orgId: connectionDto.orgId,
alias: connectionDto.alias,
label: connectionDto.label,
imageUrl: connectionDto.imageUrl,
multiUseInvitation: connectionDto.multiUseInvitation,
autoAcceptConnection: connectionDto.autoAcceptConnection,
user
};

return this.sendNats(this.connectionServiceProxy, 'create-connection', connectionDetails);
} catch (error) {
throw new RpcException(error.response);

}
return this.sendNats(this.connectionServiceProxy, 'create-connection', connectionDetails);
} catch (error) {
throw new RpcException(error.response);
}
}

getConnectionWebhook(connectionDto: ConnectionDto, id: string): Promise<{
response: object;
}> {
const payload = { connectionId: connectionDto.id, state: connectionDto.state, orgDid: connectionDto.theirDid, theirLabel: connectionDto.theirLabel, autoAcceptConnection: connectionDto.autoAcceptConnection, outOfBandId: connectionDto.outOfBandId, createDateTime: connectionDto.createdAt, lastChangedDateTime: connectionDto.updatedAt, orgId: id };
return this.sendNats(this.connectionServiceProxy, 'webhook-get-connection', payload);
}
getConnectionWebhook(
connectionDto: ConnectionDto,
id: string
): Promise<{
response: object;
}> {
const payload = { connectionDto, orgId: id };
return this.sendNats(this.connectionServiceProxy, 'webhook-get-connection', payload);
}

getUrl(referenceId: string): Promise<{
response: object;
}> {
try {
const connectionDetails = { referenceId };
return this.sendNats(this.connectionServiceProxy, 'get-connection-url', connectionDetails);
} catch (error) {
throw new RpcException(error.response);

}
getUrl(referenceId: string): Promise<{
response: object;
}> {
try {
const connectionDetails = { referenceId };
return this.sendNats(this.connectionServiceProxy, 'get-connection-url', connectionDetails);
} catch (error) {
throw new RpcException(error.response);
}
}

getConnections(user: IUserRequest, outOfBandId: string, alias: string, state: string, myDid: string, theirDid: string, theirLabel: string, orgId: string): Promise<{
response: object;
}> {
const payload = { user, outOfBandId, alias, state, myDid, theirDid, theirLabel, orgId };
return this.sendNats(this.connectionServiceProxy, 'get-all-connections', payload);
}
getConnections(
connectionSearchCriteria: IConnectionSearchinterface,
user: IUserRequest,
orgId: string
): Promise<{
response: object;
}> {
const payload = { connectionSearchCriteria, user, orgId };
return this.sendNats(this.connectionServiceProxy, 'get-all-connections', payload);
}

getConnectionsById(user: IUserRequest, connectionId: string, orgId: string): Promise<{
response: object;
}> {
const payload = { user, connectionId, orgId };
return this.sendNats(this.connectionServiceProxy, 'get-all-connections-by-connectionId', payload);
}
}
getConnectionsById(
user: IUserRequest,
connectionId: string,
orgId: string
): Promise<{
response: object;
}> {
const payload = { user, connectionId, orgId };
return this.sendNats(this.connectionServiceProxy, 'get-all-connections-by-connectionId', payload);
}
}
5 changes: 4 additions & 1 deletion apps/api-gateway/src/connection/dtos/connection.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export class CreateConnectionDto {
orgId: string;
}


export class ConnectionDto {
@ApiProperty()
@IsOptional()
Expand Down Expand Up @@ -94,4 +93,8 @@ export class ConnectionDto {
@ApiProperty()
@IsOptional()
updatedAt: string;

@ApiProperty()
@IsOptional()
contextCorrelationId: string;
}
27 changes: 27 additions & 0 deletions apps/api-gateway/src/connection/dtos/get-all-connections.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ApiProperty } from "@nestjs/swagger";
import { Type } from "class-transformer";
import { IsOptional } from "class-validator";
import { SortValue } from "../../enum";

export class GetAllConnectionsDto {
@ApiProperty({ required: false })
@IsOptional()
@Type(() => String)
searchByText: string = '';

@ApiProperty({ required: false })
@IsOptional()
pageNumber: number = 1;

@ApiProperty({ required: false })
@IsOptional()
pageSize: number = 10;

@ApiProperty({ required: false })
@IsOptional()
sorting: string = 'id';

@ApiProperty({ required: false })
@IsOptional()
sortByValue: string = SortValue.DESC;
}
10 changes: 9 additions & 1 deletion apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,12 @@ export interface ICredDeffSchemaSearchInterface {
sorting: string;
sortByValue: string;
user?: IUserRequestInterface
}
}
export interface IConnectionSearchinterface {
pageNumber: number;
pageSize: number;
sorting: string;
sortByValue: string;
searchByText: string;
user?: IUserRequestInterface
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ApiProperty } from "@nestjs/swagger";
import { Type } from "class-transformer";
import { IsOptional } from "class-validator";
import { SortValue } from "../../enum";

export class GetAllIssuedCredentialsDto {
@ApiProperty({ required: false })
@IsOptional()
pageNumber: number = 1;

@ApiProperty({ required: false })
@IsOptional()
pageSize: number = 10;

@ApiProperty({ required: false })
@IsOptional()
@Type(() => String)
searchByText: string = '';

@ApiProperty({ required: false })
@IsOptional()
sorting: string = 'id';

@ApiProperty({ required: false })
@IsOptional()
sortByValue: string = SortValue.DESC;
}
12 changes: 12 additions & 0 deletions apps/api-gateway/src/issuance/dtos/issuance.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,25 @@ export class IssuanceDto {
@IsOptional()
threadId: string;

@ApiProperty()
@IsOptional()
schemaId: string;

@ApiProperty()
@IsOptional()
credDefId: string;

@ApiProperty()
@IsOptional()
credentialAttributes: CredentialAttributes[];

@ApiProperty()
@IsOptional()
autoAcceptCredential: string;

@ApiProperty()
@IsOptional()
contextCorrelationId: string;
}


Expand Down
8 changes: 8 additions & 0 deletions apps/api-gateway/src/issuance/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,11 @@ export interface RequestPayload {
fileKey: string;
fileName: string;
}
export interface IIssuedCredentialSearchinterface {
pageNumber: number;
pageSize: number;
sorting: string;
sortByValue: string;
searchByText: string;
}

Loading