Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • eclipse/xfsc/ocm/ocm-engine
  • zdravko61/ocm-engine
  • mjuergenscg/ocm-engine
  • tsabolov/ocm-engine
  • mikesell/ocm-engine
5 results
Show changes
Showing
with 318 additions and 241 deletions
import type { ResponseType } from './response.js';
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
HttpStatus,
type ArgumentsHost,
type ExceptionFilter,
} from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';
import { ResponseType } from './response';
@Catch()
export default class ExceptionHandler implements ExceptionFilter {
constructor(private readonly httpAdapterHost: HttpAdapterHost) {}
public constructor(private readonly httpAdapterHost: HttpAdapterHost) {}
catch(exception: any, host: ArgumentsHost): void {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public catch(exception: any, host: ArgumentsHost): void {
// In certain situations `httpAdapter` might not be available in the
// constructor method, thus we should resolve it here.
const { httpAdapter } = this.httpAdapterHost;
......@@ -25,10 +27,13 @@ export default class ExceptionHandler implements ExceptionFilter {
exception.message.error || exception.message || 'Something went wrong!';
if (exception instanceof HttpException) {
const errorResponse: any = exception.getResponse();
const errorResponse: string | object = exception.getResponse();
statusCode = exception.getStatus();
message = errorResponse.error || message;
message =
(typeof errorResponse === 'object' &&
Reflect.get(errorResponse, 'error')) ||
message;
}
const responseBody: ResponseType = {
......
export interface ResponseType {
statusCode: number;
message: string;
data?: any;
error?: any;
data?: unknown;
error?: unknown;
}
import { fileURLToPath } from 'node:url';
const parentDirectory = fileURLToPath(new URL('..', import.meta.url));
const config = () => ({
PORT: Number(process.env.PORT),
nats: {
......@@ -17,10 +21,11 @@ const config = () => ({
port: 5432,
synchronize: false,
logging: false,
entities: [`${__dirname}/../**/**.model{.ts,.js}`],
entities: [`${parentDirectory}/**/**.model{.ts,.js}`],
},
ECSURL: process.env.ECSURL,
ACCEPT_MEMBERSHIP_CREDENTIALS_CONFIG: process.env.ACCEPT_MEMBERSHIP_CREDENTIALS_CONFIG,
ACCEPT_MEMBERSHIP_CREDENTIALS_CONFIG:
process.env.ACCEPT_MEMBERSHIP_CREDENTIALS_CONFIG,
TSA_URL: process.env.TSA_URL,
});
export default config;
import * as Joi from 'joi';
import Joi from 'joi';
const validationSchema = Joi.object({
DATABASE_URL: Joi.string().required(),
......
import type { ResponseType } from '../../common/response.js';
import type CredentialDefLedgerDto from '../entities/credentialDefLedger-entity.js';
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
import type { Response } from 'express';
import {
Body,
Controller,
......@@ -10,26 +15,26 @@ import {
Res,
Version,
} from '@nestjs/common';
import { Response } from 'express';
import logger from '@utils/logger';
import CredentialDefService from '@src/credentialDef/services/service';
import { ResponseType } from '@src/common/response';
import CredentialDefDto from '@src/credentialDef/entities/credentialDef-entity';
import {
ApiBody,
ApiOperation,
ApiParam,
ApiQuery,
ApiOperation,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { PrismaClientUnknownRequestError } from '@prisma/client/runtime';
import CredentialDefLedgerDto from '@src/credentialDef/entities/credentialDefLedger-entity';
import { Prisma } from '@prisma/client';
import logger from '../../utils/logger.js';
import CredentialDefDto from '../entities/credentialDef-entity.js';
import CredentialDefService from '../services/service.js';
@ApiTags('Credential Definitions')
@Controller('credentialDef')
export default class CredentialDefController {
constructor(private readonly credentialDefService: CredentialDefService) {}
public constructor(
private readonly credentialDefService: CredentialDefService,
) {}
@Version(['1'])
@ApiQuery({ name: 'page', required: false })
......@@ -38,7 +43,8 @@ export default class CredentialDefController {
@Get('')
@ApiOperation({
summary: 'Fetch a list of credential definitions',
description: 'This call provides the capability to search created credential definitions by using pagination and filter parameter (schemaID) to select credential definitions. This call returns a list of credential definitions and overall count of records. Using a credential definition from that list you can issue credential so some connection'
description:
'This call provides the capability to search created credential definitions by using pagination and filter parameter (schemaID) to select credential definitions. This call returns a list of credential definitions and overall count of records. Using a credential definition from that list you can issue credential so some connection',
})
@ApiResponse({
status: HttpStatus.OK,
......@@ -123,7 +129,7 @@ export default class CredentialDefController {
},
},
})
async findCredentialDef(
public async findCredentialDef(
@Query()
query: {
pageSize: string;
......@@ -157,9 +163,11 @@ export default class CredentialDefController {
};
}
return response.send(res);
} catch (error: any) {
logger.error(error && error.message);
throw new InternalServerErrorException(`Error: ${error.message}`);
} catch (error: unknown) {
logger.error(error instanceof Error && error.message);
throw new InternalServerErrorException(
`Error: ${error instanceof Error ? error.message : error}`,
);
}
}
......@@ -168,7 +176,8 @@ export default class CredentialDefController {
@Get('/:id')
@ApiOperation({
summary: 'Fetch credential definition by id',
description: 'This call provides the capability to get credential definition data by providing id of credential definition. The credential definition data is the same which is returned from /v1/connections endpoint and contains generic information about credential definition like schemaID, name, credDefId, isAutoIssue, isRevokable, expiryHours, createdBy, createdDate, updatedBy, updatedDate'
description:
'This call provides the capability to get credential definition data by providing id of credential definition. The credential definition data is the same which is returned from /v1/connections endpoint and contains generic information about credential definition like schemaID, name, credDefId, isAutoIssue, isRevokable, expiryHours, createdBy, createdDate, updatedBy, updatedDate',
})
@ApiResponse({
status: HttpStatus.OK,
......@@ -240,7 +249,7 @@ export default class CredentialDefController {
},
},
})
async findCredentialDefById(
public async findCredentialDefById(
@Param('id') id: string,
@Res() response: Response,
) {
......@@ -266,7 +275,7 @@ export default class CredentialDefController {
}
return response.send(res);
} catch (error) {
if (error instanceof PrismaClientUnknownRequestError) {
if (error instanceof Prisma.PrismaClientUnknownRequestError) {
throw new InternalServerErrorException(error.message);
} else {
throw new InternalServerErrorException(error);
......@@ -279,7 +288,8 @@ export default class CredentialDefController {
@Post('')
@ApiOperation({
summary: 'Create a new credential definition',
description: 'This call provides the capability to create new credential definition by providing schema id, name, createdBy, auto-issue and other information required by this method. This call returns an object contains information abut this credential definition (type CredentialDefDto). You can use this credential definition to issue credentials to some connection'
description:
'This call provides the capability to create new credential definition by providing schema id, name, createdBy, auto-issue and other information required by this method. This call returns an object contains information abut this credential definition (type CredentialDefDto). You can use this credential definition to issue credentials to some connection',
})
@ApiResponse({
status: HttpStatus.CREATED,
......@@ -385,7 +395,7 @@ export default class CredentialDefController {
},
},
})
async createCredentialDef(
public async createCredentialDef(
@Body() credentialDefDto: CredentialDefDto,
@Res() response: Response,
) {
......@@ -462,7 +472,7 @@ export default class CredentialDefController {
}
return response.send(res);
} catch (error) {
if (error instanceof PrismaClientUnknownRequestError) {
if (error instanceof Prisma.PrismaClientUnknownRequestError) {
throw new InternalServerErrorException(error.message);
} else {
throw new InternalServerErrorException(error);
......
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsString, IsNotEmpty, IsBoolean } from 'class-validator';
import { IsBoolean, IsNotEmpty, IsString } from 'class-validator';
export default class CredentialDefDto {
@IsString()
id: string;
public id: string;
@IsString()
@IsNotEmpty()
@ApiProperty()
schemaID: string;
public schemaID: string;
@IsString()
@IsNotEmpty()
@ApiProperty()
name: string;
public name: string;
@IsString()
credDefId: string;
public credDefId: string;
@IsBoolean()
supportRevocation?: boolean;
public supportRevocation?: boolean;
@IsBoolean()
@ApiProperty()
isRevokable: boolean;
public isRevokable: boolean;
@IsBoolean()
@ApiProperty()
isAutoIssue: boolean;
public isAutoIssue: boolean;
@IsString()
@ApiProperty()
// Number of hours of Credential validity
expiryHours: string;
public expiryHours: string;
@IsString()
@ApiProperty()
createdBy: string;
public createdBy: string;
@IsString()
createdDate: Date;
public createdDate: Date;
@IsString()
updatedBy: string;
public updatedBy: string;
@IsString()
updatedDate: Date;
public updatedDate: Date;
@IsString()
tag?: string;
public tag?: string;
@IsString()
@ApiPropertyOptional()
type?: string;
public type?: string;
}
......@@ -2,11 +2,11 @@ import { IsString, IsBoolean } from 'class-validator';
export default class CredentialDefLedgerDto {
@IsString()
schemaId: string;
public schemaId: string;
@IsBoolean()
supportRevocation?: boolean;
public supportRevocation?: boolean;
@IsString()
tag?: string;
public tag?: string;
}
......@@ -3,50 +3,50 @@ import { IsString, IsNotEmpty, IsBoolean } from 'class-validator';
export default class CredentialDefReqDto {
@IsString()
id: string;
public id: string;
@IsString()
@IsNotEmpty()
@ApiProperty()
schemaID: string;
public schemaID: string;
@IsString()
@IsNotEmpty()
@ApiProperty()
name: string;
public name: string;
@IsString()
credDefId: string;
public credDefId: string;
@IsBoolean()
supportRevocation?: boolean;
public supportRevocation?: boolean;
@IsBoolean()
@ApiProperty()
isRevokable: boolean;
public isRevokable: boolean;
@IsBoolean()
@ApiProperty()
isAutoIssue: boolean;
public isAutoIssue: boolean;
@IsString()
@ApiProperty()
// Number of hours of Credential validity
expiryHours: string;
public expiryHours: string;
@IsString()
@ApiProperty()
createdBy: string;
public createdBy: string;
@IsString()
createdDate: Date;
public createdDate: Date;
@IsString()
updatedBy: string;
public updatedBy: string;
@IsString()
updatedDate: Date;
public updatedDate: Date;
@IsString()
tag?: string;
public tag?: string;
}
import SchemasService from '@schemas/services/service';
import { Module } from '@nestjs/common';
import PrismaService from '@DB/prisma.service';
import { HttpModule } from '@nestjs/axios';
import CredentialDefService from '@src/credentialDef/services/service';
import CredentialDefController from '@src/credentialDef/controller/controller';
import NatsClientService from '@src/client/nats.client';
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { NATSServices } from '@common/constants';
import RestClientService from '@src/client/rest.client';
import config from '@config/config';
import NatsClientService from '../client/nats.client.js';
import RestClientService from '../client/rest.client.js';
import { NATSServices } from '../common/constants.js';
import config from '../config/config.js';
import PrismaService from '../prisma/prisma.service.js';
import SchemasService from '../schemas/services/service.js';
import CredentialDefController from './controller/controller.js';
import CredentialDefService from './services/service.js';
@Module({
imports: [
......
import type { Prisma } from '@prisma/client';
import { Injectable } from '@nestjs/common';
import PrismaService from '@DB/prisma.service';
import { Prisma } from '@prisma/client';
import PrismaService from '../../prisma/prisma.service.js';
@Injectable()
export default class CredentialDefRepository {
constructor(private readonly prismaService: PrismaService) {}
public constructor(private readonly prismaService: PrismaService) {}
async createCredDef(data: Prisma.CredentialDefCreateInput) {
public async createCredDef(data: Prisma.CredentialDefCreateInput) {
const credDef = await this.prismaService.credentialDef.create({
data,
});
......@@ -27,7 +29,7 @@ export default class CredentialDefRepository {
return credDef;
}
async findCredentialDef(params: {
public async findCredentialDef(params: {
skip?: number;
take?: number;
cursor?: Prisma.CredentialDefWhereUniqueInput;
......@@ -49,7 +51,7 @@ export default class CredentialDefRepository {
]);
}
async findUniqueCredentialDef(params: {
public async findUniqueCredentialDef(params: {
where: Prisma.CredentialDefWhereUniqueInput;
}) {
const { where } = params;
......
import logger from '@utils/logger';
import type SchemaDto from '../../schemas/entities/schema-entity.js';
import type CredentialDefDto from '../entities/credentialDef-entity.js';
import type CredentialDefLedgerDto from '../entities/credentialDefLedger-entity.js';
import type { Prisma } from '@prisma/client';
import { Injectable } from '@nestjs/common';
import CredentialDefDto from '@src/credentialDef/entities/credentialDef-entity';
import CredentialDefRepository from '@src/credentialDef/repository/credentialDef.respository';
import PrismaService from '@DB/prisma.service';
import CredentialDefLedgerDto from '@src/credentialDef/entities/credentialDefLedger-entity';
import { Prisma } from '@prisma/client';
import pagination from '@utils/pagination';
import RestClientService from '@src/client/rest.client';
import { ConfigService } from '@nestjs/config';
import SchemasService from '@schemas/services/service';
import SchemaDto from '@src/schemas/entities/schema-entity';
import CredentialTypeRepository from '@src/issue-credential/repository/credentialType.repository';
import RestClientService from '../../client/rest.client.js';
import CredentialTypeRepository from '../../issue-credential/repository/credentialType.repository.js';
import PrismaService from '../../prisma/prisma.service.js';
import SchemasService from '../../schemas/services/service.js';
import logger from '../../utils/logger.js';
import pagination from '../../utils/pagination.js';
import CredentialDefRepository from '../repository/credentialDef.respository.js';
@Injectable()
export default class CredentialDefService {
......@@ -18,7 +20,7 @@ export default class CredentialDefService {
private credentialTypeRepository: CredentialTypeRepository;
constructor(
public constructor(
private readonly prismaService: PrismaService,
private readonly restClient: RestClientService,
private readonly configService: ConfigService,
......@@ -33,7 +35,7 @@ export default class CredentialDefService {
);
}
async createCredDef(credentialDefDtoPar: CredentialDefDto) {
public async createCredDef(credentialDefDtoPar: CredentialDefDto) {
const credentialDefDto: CredentialDefDto = credentialDefDtoPar;
const schema = await this.schemaService.findBySchemaId(
credentialDefDto.schemaID,
......@@ -73,7 +75,11 @@ export default class CredentialDefService {
return this.credentialDefRepository.createCredDef(credentialDefDto);
}
async findCredentialDef(pageSize: number, page: number, getSchemaID: string) {
public async findCredentialDef(
pageSize: number,
page: number,
getSchemaID: string,
) {
let query: {
skip?: number;
take?: number;
......@@ -90,7 +96,7 @@ export default class CredentialDefService {
return this.credentialDefRepository.findCredentialDef(query);
}
async findCredentialDefBySchemaIdAndCredDefId(data: {
public async findCredentialDefBySchemaIdAndCredDefId(data: {
schemaID: string;
credDefId: string;
}) {
......@@ -99,7 +105,7 @@ export default class CredentialDefService {
});
}
async findCredentialDefBySchemaIdDesc(data: { schemaID: string }) {
public async findCredentialDefBySchemaIdDesc(data: { schemaID: string }) {
return this.credentialDefRepository.findCredentialDef({
where: data,
orderBy: {
......@@ -108,13 +114,13 @@ export default class CredentialDefService {
});
}
async findCredentialDefById(id: string) {
public async findCredentialDefById(id: string) {
return this.credentialDefRepository.findCredentialDef({
where: { credDefId: id },
});
}
async checkCredDefByNameAndSchemaID(createSchema: CredentialDefDto) {
public async checkCredDefByNameAndSchemaID(createSchema: CredentialDefDto) {
return this.credentialDefRepository.findCredentialDef({
where: {
schemaID: {
......@@ -127,7 +133,7 @@ export default class CredentialDefService {
});
}
async createCredDefOnLedger(credentialDefDto: CredentialDefLedgerDto) {
public async createCredDefOnLedger(credentialDefDto: CredentialDefLedgerDto) {
const agentUrl = this.configService.get('agent.AGENT_URL');
return this.restClient.post(
`${agentUrl}/credential-definitions/`,
......
import credDefStub from '@src/credentialDef/tests/stubs/credDef.stub';
import credDefStub from '../stubs/credDef.stub.js';
const CredentialDefServiceMock = jest.fn().mockReturnValue({
createCredDef: jest.fn().mockReturnValue(credDefStub()),
......
import { Test, TestingModule } from '@nestjs/testing';
import httpMocks from 'node-mocks-http';
import type { TestingModule } from '@nestjs/testing';
import type { Response } from 'express';
import CredentialDefController from '@credentialDef/controller/controller';
import CredentialDefService from '@credentialDef/services/service';
import CredentialDefServiceMock from '@credentialDef/tests/__mocks__/service';
import credDefStub from '@credentialDef/tests/stubs/credDef.stub';
import { HttpStatus } from '@nestjs/common';
import { Response } from 'express';
import { ConfigService } from '@nestjs/config';
import { Test } from '@nestjs/testing';
import { createResponse } from 'node-mocks-http';
import CredentialDefController from '../controller/controller.js';
import CredentialDefService from '../services/service.js';
import CredentialDefServiceMock from './__mocks__/service.js';
import credDefStub from './stubs/credDef.stub.js';
describe('CredentialDefController', () => {
let credentialDefController: CredentialDefController;
......@@ -42,7 +45,7 @@ describe('CredentialDefController', () => {
page: string;
schemaID: string;
};
let credDefResponse: Response<string, Record<string, any>>;
let credDefResponse: Response<string, Record<string, unknown>>;
beforeEach(async () => {
query = {
......@@ -51,7 +54,7 @@ describe('CredentialDefController', () => {
schemaID: credDefStub().schemaID,
};
const response = httpMocks.createResponse();
const response = createResponse();
credDefResponse = await credentialDefController.findCredentialDef(
query,
response,
......@@ -79,12 +82,12 @@ describe('CredentialDefController', () => {
describe('findCredentialDefById()', () => {
let credDefID: string;
let credDef: Response<string, Record<string, any>>;
let credDef: Response<string, Record<string, unknown>>;
beforeEach(async () => {
credDefID = credDefStub().id;
const response = httpMocks.createResponse();
const response = createResponse();
credDef = await credentialDefController.findCredentialDefById(
credDefID,
response,
......@@ -108,10 +111,10 @@ describe('CredentialDefController', () => {
});
describe('createCredDef()', () => {
let credDef: Response<string, Record<string, any>>;
let credDef: Response<string, Record<string, unknown>>;
beforeEach(async () => {
const response = httpMocks.createResponse();
const response = createResponse();
credDef = await credentialDefController.createCredentialDef(
credDefStub(),
response,
......
import { Test, TestingModule } from '@nestjs/testing';
import PrismaService from '@DB/prisma.service';
import type { TestingModule } from '@nestjs/testing';
import { HttpModule } from '@nestjs/axios';
import NatsClientService from '@src/client/nats.client';
import PrismaServiceMock from '@src/prisma/tests/__mocks__/prisma.service';
import NatsClientServiceMock from '@src/client/tests/__mocks__/nats.client';
import RestClientService from '@src/client/rest.client';
import RestClientServiceMock from '@src/client/tests/__mocks__/rest.client';
import CredentialDefModule from '../module';
import CredentialDefService from '../services/service';
import CredentialDefServiceMock from './__mocks__/service';
import { Test } from '@nestjs/testing';
import NatsClientService from '../../client/nats.client.js';
import RestClientService from '../../client/rest.client.js';
import NatsClientServiceMock from '../../client/tests/__mocks__/nats.client.js';
import RestClientServiceMock from '../../client/tests/__mocks__/rest.client.js';
import PrismaService from '../../prisma/prisma.service.js';
import PrismaServiceMock from '../../prisma/tests/__mocks__/prisma.service.js';
import CredentialDefModule from '../module.js';
import CredentialDefService from '../services/service.js';
import CredentialDefServiceMock from './__mocks__/service.js';
describe('CredentialDefModule', () => {
let credentialDefModule: CredentialDefModule;
......
import CredentialDefService from '@credentialDef/services/service';
import type { TestingModule } from '@nestjs/testing';
import type { CredentialDef } from '@prisma/client';
import { HttpModule } from '@nestjs/axios';
import { Test, TestingModule } from '@nestjs/testing';
import { CredentialDef } from '@prisma/client';
import NatsClientService from '@src/client/nats.client';
import NatsClientServiceMock from '@src/client/tests/__mocks__/nats.client';
import PrismaService from '@src/prisma/prisma.service';
import PrismaServiceMock from '@src/prisma/tests/__mocks__/prisma.service';
import RestClientService from '@src/client/rest.client';
import RestClientServiceMock from '@src/client/tests/__mocks__/rest.client';
import { ConfigService } from '@nestjs/config';
import SchemasService from '@src/schemas/services/service';
import SchemasServiceMock from '@src/schemas/tests/__mocks__/service';
import credDefStub from './stubs/credDef.stub';
import { Test } from '@nestjs/testing';
import NatsClientService from '../../client/nats.client.js';
import RestClientService from '../../client/rest.client.js';
import NatsClientServiceMock from '../../client/tests/__mocks__/nats.client.js';
import RestClientServiceMock from '../../client/tests/__mocks__/rest.client.js';
import PrismaService from '../../prisma/prisma.service.js';
import PrismaServiceMock from '../../prisma/tests/__mocks__/prisma.service.js';
import SchemasService from '../../schemas/services/service.js';
import SchemasServiceMock from '../../schemas/tests/__mocks__/service.js';
import CredentialDefService from '../services/service.js';
import credDefStub from './stubs/credDef.stub.js';
describe('CredentialDefService', () => {
let credDefService: CredentialDefService;
......@@ -136,9 +140,8 @@ describe('CredentialDefService', () => {
let credDefResponse: Array<number | CredentialDef[]>;
beforeEach(async () => {
credDefResponse = await credDefService.checkCredDefByNameAndSchemaID(
credDefStub(),
);
credDefResponse =
await credDefService.checkCredDefByNameAndSchemaID(credDefStub());
});
it('should call findMany() from PrismaService.credentialDef', async () => {
......
import CredentialDefDto from '@credentialDef/entities/credentialDef-entity';
import type CredentialDefDto from '../../entities/credentialDef-entity.js';
const credDefStub = (): CredentialDefDto =>
({
......@@ -15,6 +15,6 @@ const credDefStub = (): CredentialDefDto =>
updatedBy: 'cred-def-stub-updated-by-id',
updatedDate: new Date(2022),
tag: 'cred-def-stub-tag',
} as CredentialDefDto);
}) as CredentialDefDto;
export default credDefStub;
import { Controller, Get, Version, HttpStatus } from '@nestjs/common';
import type { ResponseType } from '../common/response.js';
import { ResponseType } from '@common/response';
import {ApiOperation, ApiResponse} from '@nestjs/swagger';
import { Controller, Get, HttpStatus, Version } from '@nestjs/common';
import { ApiOperation, ApiResponse } from '@nestjs/swagger';
@Controller('health')
export default class HealthController {
res: ResponseType;
public res: ResponseType;
@Version(['1'])
@Get()
@ApiOperation({
summary: 'Health check',
description: 'This call provides the capability to check the service is working and up. The call returns 200 Status Code and current server time in json body'
description:
'This call provides the capability to check the service is working and up. The call returns 200 Status Code and current server time in json body',
})
@ApiResponse({
status: HttpStatus.OK,
......@@ -31,7 +32,7 @@ export default class HealthController {
},
},
})
getHealth() {
public getHealth() {
this.res = {
statusCode: HttpStatus.OK,
message: `${new Date()}`,
......
import type { ResponseType } from '../../common/response.js';
import type { TestingModule } from '@nestjs/testing';
import { HttpStatus } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { ResponseType } from '@src/common/response';
import { Test } from '@nestjs/testing';
import HealthController from '../health.controller';
import HealthController from '../health.controller.js';
describe('HealthController', () => {
let healthController: HealthController;
......
import OfferCredentialDto from '@issueCredential/entities/entity';
import logger from '@utils/logger';
import CredentialDto from '@issueCredential/entities/credential.entity';
import type { ResponseType } from '../../common/response.js';
import type CredentialDto from '../entities/credential.entity.js';
import type CredentialStateDto from '../entities/credential.state.entity.js';
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
import type { Response } from 'express';
import {
BadRequestException,
Body,
Controller,
Delete,
Get,
HttpException,
HttpStatus,
InternalServerErrorException,
NotFoundException,
Param,
Patch,
Post,
PreconditionFailedException,
Query,
Res,
Version,
Patch,
NotFoundException,
BadRequestException,
HttpException,
PreconditionFailedException,
Delete,
} from '@nestjs/common';
import AttestationService from '@src/issue-credential/services/service';
import { ResponseType } from '@src/common/response';
import {ApiBody, ApiOperation, ApiQuery, ApiResponse, ApiTags} from '@nestjs/swagger';
import CredentialStateDto from '@issueCredential/entities/credential.state.entity';
import GetIssueCredentialsDto from '@src/issue-credential/entities/get-issue-credentials.dto';
import GetCredentialParams from '@issueCredential/entities/get.credential.params';
import GetCredentialQuery from '@issueCredential/entities/get.credential.query';
import { PrismaClientUnknownRequestError } from '@prisma/client/runtime';
import { Response } from 'express';
import { ConfigService } from '@nestjs/config';
import { EventPattern, MessagePattern } from '@nestjs/microservices';
import {
ApiBody,
ApiOperation,
ApiQuery,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { Prisma } from '@prisma/client';
import {
Abstraction,
NATSServices,
PrismaErrorCode,
} from '@src/common/constants';
import { EventPattern, MessagePattern } from '@nestjs/microservices';
import { ConfigService } from '@nestjs/config';
import UpdateSchemaIdByTypeDto from '@issueCredential/entities/updatecredDefIdByType.entity';
import CredentialDefService from '@credentialDef/services/service';
import CredentialTypeDto from '@issueCredential/entities/credentialType.entity';
import ProposeCredentialDto from '@issueCredential/entities/propose-credential.dto';
import UserInfoService from '@userInfo/services/service';
import SchemasService from '@src/schemas/services/service';
} from '../../common/constants.js';
import CredentialDefService from '../../credentialDef/services/service.js';
import SchemasService from '../../schemas/services/service.js';
import UserInfoService from '../../userInfo/services/service.js';
import logger from '../../utils/logger.js';
import CredentialTypeDto from '../entities/credentialType.entity.js';
import OfferCredentialDto from '../entities/entity.js';
import GetIssueCredentialsDto from '../entities/get-issue-credentials.dto.js';
import GetCredentialParams from '../entities/get.credential.params.js';
import GetCredentialQuery from '../entities/get.credential.query.js';
import ProposeCredentialDto from '../entities/propose-credential.dto.js';
import UpdateSchemaIdByTypeDto from '../entities/updatecredDefIdByType.entity.js';
import AttestationService from '../services/service.js';
@ApiTags('Credentials')
@Controller()
export default class AttestationController {
name: string;
public name: string;
constructor(
public constructor(
private readonly attestationService: AttestationService,
private readonly credentialDefService: CredentialDefService,
private readonly userInfoService: UserInfoService,
......@@ -60,7 +69,8 @@ export default class AttestationController {
@Post('create-offer-credential')
@ApiOperation({
summary: 'Send credential offer to a connection',
description: 'This call provides the capability to offer credentials to a connection. You need to provide information about credential definition, connection and attributes which will be send to connection. Initial state of this is offer-sent (workflow is here https://github.com/hyperledger/aries-rfcs/tree/main/features/0036-issue-credential). This call returns information about this credential offer. From user perspective this call means that as organization (e.g. Faber university) I want to start issuing crendentials to student (Alice, holder)'
description:
'This call provides the capability to offer credentials to a connection. You need to provide information about credential definition, connection and attributes which will be send to connection. Initial state of this is offer-sent (workflow is here https://github.com/hyperledger/aries-rfcs/tree/main/features/0036-issue-credential). This call returns information about this credential offer. From user perspective this call means that as organization (e.g. Faber university) I want to start issuing crendentials to student (Alice, holder)',
})
@ApiResponse({
status: HttpStatus.CREATED,
......@@ -206,7 +216,7 @@ export default class AttestationController {
},
},
})
async createOfferCredential(
public async createOfferCredential(
@Body() connectionCreate: OfferCredentialDto,
@Res() response: Response,
) {
......@@ -276,7 +286,8 @@ export default class AttestationController {
@Post('create-propose-credential')
@ApiOperation({
summary: 'Send credential proposal to a connection',
description: 'This call provides the capability to send propose crendential request to a connection. You need to provide information about credential definition, connection and attributes which you want to use for creating credentials. Initial state of this is proposal-sent (workflow is here https://github.com/hyperledger/aries-rfcs/tree/main/features/0036-issue-credential). This call returns information about this credential proposal. From user perspective this call means that as user (e.g. student) I want to ask organization (e.g. Faber university) to initiate issuing credentials for me using provided data'
description:
'This call provides the capability to send propose crendential request to a connection. You need to provide information about credential definition, connection and attributes which you want to use for creating credentials. Initial state of this is proposal-sent (workflow is here https://github.com/hyperledger/aries-rfcs/tree/main/features/0036-issue-credential). This call returns information about this credential proposal. From user perspective this call means that as user (e.g. student) I want to ask organization (e.g. Faber university) to initiate issuing credentials for me using provided data',
})
@ApiResponse({
status: HttpStatus.CREATED,
......@@ -384,15 +395,14 @@ export default class AttestationController {
},
},
})
async createProposeCredential(
public async createProposeCredential(
@Body() connectionCreate: ProposeCredentialDto,
@Res() response: Response,
) {
try {
let res: ResponseType;
const proposeCredential = await this.attestationService.proposeCredential(
connectionCreate,
);
const proposeCredential =
await this.attestationService.proposeCredential(connectionCreate);
if (proposeCredential) {
res = {
......@@ -418,9 +428,12 @@ export default class AttestationController {
@Post('accept-request/:credentialId')
@ApiOperation({
summary: 'Accept credential request by credential id',
description: 'Accept a credential request as issuer (by sending a credential message) to the connection associated with the credential record.'
description:
'Accept a credential request as issuer (by sending a credential message) to the connection associated with the credential record.',
})
async acceptOfferCredential(@Param() params: { credentialId: string }) {
public async acceptOfferCredential(
@Param() params: { credentialId: string },
) {
try {
const res: ResponseType = {
statusCode: HttpStatus.ACCEPTED,
......@@ -439,9 +452,12 @@ export default class AttestationController {
@Post('accept-proposal/:credentialId')
@ApiOperation({
summary: 'Accept credential proposal by credential id',
description: 'Accept a credential proposal as issuer (by sending a credential offer message) to the connection associated with the credential record.'
description:
'Accept a credential proposal as issuer (by sending a credential offer message) to the connection associated with the credential record.',
})
async acceptProposeCredential(@Param() params: { credentialId: string }) {
public async acceptProposeCredential(
@Param() params: { credentialId: string },
) {
try {
if (!params.credentialId) {
throw new BadRequestException('Invalid credential ID');
......@@ -455,10 +471,10 @@ export default class AttestationController {
),
};
return res;
} catch (error: any) {
} catch (error: unknown) {
throw new HttpException(
error?.message || 'Internal server error',
error?.status || 500,
Reflect.get(error || {}, 'message') || 'Internal server error',
Reflect.get(error || {}, 'status') || 500,
);
}
}
......@@ -467,9 +483,12 @@ export default class AttestationController {
@Post('accept-offer/:credentialId')
@ApiOperation({
summary: 'Accept credential offer by credential id',
description: 'Accept a credential offer as holder (by sending a credential request message) to the connection associated with the credential record.'
description:
'Accept a credential offer as holder (by sending a credential request message) to the connection associated with the credential record.',
})
async acceptCredentialOffer(@Param() params: { credentialId: string }) {
public async acceptCredentialOffer(
@Param() params: { credentialId: string },
) {
try {
if (!params.credentialId) {
throw new BadRequestException('Invalid credential ID');
......@@ -483,10 +502,10 @@ export default class AttestationController {
),
};
return res;
} catch (error: any) {
} catch (error: unknown) {
throw new HttpException(
error?.message || 'Internal server error',
error?.status || 500,
Reflect.get(error || {}, 'message') || 'Internal server error',
Reflect.get(error || {}, 'status') || 500,
);
}
}
......@@ -495,9 +514,10 @@ export default class AttestationController {
@Post('accept-credential/:credentialId')
@ApiOperation({
summary: 'Accept credentials by credential id',
description: 'Accept a credential as holder (by sending a credential acknowledgement message) to the connection associated with the credential record.'
description:
'Accept a credential as holder (by sending a credential acknowledgement message) to the connection associated with the credential record.',
})
async acceptCredential(@Param() params: { credentialId: string }) {
public async acceptCredential(@Param() params: { credentialId: string }) {
try {
if (!params.credentialId) {
throw new BadRequestException('Invalid credential ID');
......@@ -511,10 +531,10 @@ export default class AttestationController {
),
};
return res;
} catch (error: any) {
} catch (error: unknown) {
throw new HttpException(
error?.message || 'Internal server error',
error?.status || 500,
Reflect.get(error || {}, 'message') || 'Internal server error',
Reflect.get(error || {}, 'status') || 500,
);
}
}
......@@ -524,7 +544,9 @@ export default class AttestationController {
@EventPattern({
endpoint: `${Abstraction.NATS_ENDPOINT}/${Abstraction.CREDENTIAL_STATE_CHANGED}`,
})
async webHookCredentials(body: { credentialRecord: CredentialStateDto }) {
public async webHookCredentials(body: {
credentialRecord: CredentialStateDto;
}) {
const credentialsCreate = body.credentialRecord;
logger.info(
`credentials webhook call data ${JSON.stringify(credentialsCreate)}`,
......@@ -575,7 +597,9 @@ export default class AttestationController {
credentialsType?.schemaId === credentialObj.schemaId &&
credentialsCreate.state === AttestationService.status.DONE
) {
this.attestationService.connectionTrusted(credentialObj.connectionId);
await this.attestationService.connectionTrusted(
credentialObj.connectionId,
);
}
res = {
statusCode: HttpStatus.OK,
......@@ -592,7 +616,8 @@ export default class AttestationController {
@Get('credential-info/:id')
@ApiOperation({
summary: 'Fetch credential information by credential id',
description: 'This call provides the capability to get credential information by credential id. This call returns a credential record (CredentialRecord type with fields connectionId, threadId, credentialId, state, autoAcceptCredential, errorMessage, proposalMessage, offerMessage, requestMessage, credentialMessage, credentialAttributes, linkedAttachments and others). This request get credential data directly from agent, so you can use this endpoint to get some additional info which is not presented in /v1/credential/{id}'
description:
'This call provides the capability to get credential information by credential id. This call returns a credential record (CredentialRecord type with fields connectionId, threadId, credentialId, state, autoAcceptCredential, errorMessage, proposalMessage, offerMessage, requestMessage, credentialMessage, credentialAttributes, linkedAttachments and others). This request get credential data directly from agent, so you can use this endpoint to get some additional info which is not presented in /v1/credential/{id}',
})
@ApiResponse({
status: HttpStatus.OK,
......@@ -626,7 +651,7 @@ export default class AttestationController {
},
},
})
async getCredentialInfo(
public async getCredentialInfo(
@Param() params: GetCredentialParams,
@Res() response: Response,
) {
......@@ -669,7 +694,7 @@ export default class AttestationController {
// }
return response.send(res);
} catch (error) {
if (error instanceof PrismaClientUnknownRequestError) {
if (error instanceof Prisma.PrismaClientUnknownRequestError) {
throw new InternalServerErrorException(error.message);
} else {
throw new InternalServerErrorException(error);
......@@ -681,7 +706,8 @@ export default class AttestationController {
@Delete('delete-credential/:id')
@ApiOperation({
summary: 'Delete credential by id',
description: 'This call provides the capability to delete credential (request/offer/proposal) by provided credential id'
description:
'This call provides the capability to delete credential (request/offer/proposal) by provided credential id',
})
@ApiResponse({
status: HttpStatus.OK,
......@@ -717,7 +743,7 @@ export default class AttestationController {
},
},
})
async deleteCredential(
public async deleteCredential(
@Param() params: GetCredentialParams,
@Res() response: Response,
) {
......@@ -741,7 +767,7 @@ export default class AttestationController {
return response.send(res);
} catch (error) {
if (error instanceof PrismaClientUnknownRequestError) {
if (error instanceof Prisma.PrismaClientUnknownRequestError) {
throw new InternalServerErrorException(error.message);
} else {
throw new InternalServerErrorException(error);
......@@ -753,7 +779,8 @@ export default class AttestationController {
@Get('credential')
@ApiOperation({
summary: 'Fetch a list of credentials',
description: 'This call provides the capability to search credentials by using pagination and filter parameters to select credentials. This call returns a list of credentials and overall count of records. Filter supports following parameters: page, pageSize, isReceived, threadId, state, credDefId, createdDateStart, createdDateEnd, updatedDateStart, updatedDateEnd, expirationDateStart, expirationDateEnd, connectionId, principalDid'
description:
'This call provides the capability to search credentials by using pagination and filter parameters to select credentials. This call returns a list of credentials and overall count of records. Filter supports following parameters: page, pageSize, isReceived, threadId, state, credDefId, createdDateStart, createdDateEnd, updatedDateStart, updatedDateEnd, expirationDateStart, expirationDateEnd, connectionId, principalDid',
})
@ApiQuery({ name: 'page', required: false })
@ApiQuery({ name: 'pageSize', required: false })
......@@ -794,8 +821,8 @@ export default class AttestationController {
createdDate: '1970-01-01T00:00:09.761Z',
updatedDate: '1970-01-01T00:00:09.761Z',
expirationDate: '2070-01-01T00:00:09.756Z',
}
]
},
],
},
},
},
......@@ -838,7 +865,7 @@ export default class AttestationController {
},
},
})
async getCredentialList(
public async getCredentialList(
@Query() query: GetCredentialQuery,
@Res() response: Response,
) {
......@@ -909,7 +936,7 @@ export default class AttestationController {
}
return response.send(res);
} catch (error) {
if (error instanceof PrismaClientUnknownRequestError) {
if (error instanceof Prisma.PrismaClientUnknownRequestError) {
throw new InternalServerErrorException(error.message);
} else {
throw new InternalServerErrorException(error);
......@@ -921,7 +948,8 @@ export default class AttestationController {
@Get('credential/:id')
@ApiOperation({
summary: 'Fetch credential by id',
description: 'This call provides the capability to get credential data by providing credential id. The credential definition data is the same which is returned from /v1/credential endpoint and contains generic information about credential like credentialId, credDefId, threadId, state, principalDid, connectionId, createdDate, updatedDate, expirationDate'
description:
'This call provides the capability to get credential data by providing credential id. The credential definition data is the same which is returned from /v1/credential endpoint and contains generic information about credential like credentialId, credDefId, threadId, state, principalDid, connectionId, createdDate, updatedDate, expirationDate',
})
@ApiResponse({
status: HttpStatus.OK,
......@@ -987,7 +1015,7 @@ export default class AttestationController {
},
},
})
async getCredential(
public async getCredential(
@Param() params: GetCredentialParams,
@Query() query: GetCredentialQuery,
@Res() response: Response,
......@@ -1013,7 +1041,7 @@ export default class AttestationController {
}
return response.send(res);
} catch (error) {
if (error instanceof PrismaClientUnknownRequestError) {
if (error instanceof Prisma.PrismaClientUnknownRequestError) {
throw new InternalServerErrorException(error.message);
} else {
throw new InternalServerErrorException(error);
......@@ -1024,7 +1052,7 @@ export default class AttestationController {
@MessagePattern({
endpoint: `${NATSServices.SERVICE_NAME}/offerMemberShipCredentials`,
})
async offerMemberShipCredentials(data: {
public async offerMemberShipCredentials(data: {
status: string;
connectionId: string;
theirLabel: string;
......@@ -1043,7 +1071,6 @@ export default class AttestationController {
and lint does not allow more then 100 characters on same line.
*/
// eslint-disable-next-line max-len
const [, [credentialDef]] =
await this.credentialDefService.findCredentialDefBySchemaIdDesc({
schemaID: credentialsType?.schemaId,
......@@ -1075,7 +1102,7 @@ export default class AttestationController {
userInfo.subjectDID = data.theirDid;
for (let i = 0; i < schemaAttributes.length; i += 1) {
const attribute: any = schemaAttributes[i];
const attribute: Record<string, string> = schemaAttributes[i];
if (attribute.name in userInfo) {
attributes.push({
......@@ -1140,7 +1167,8 @@ export default class AttestationController {
@ApiBody({ type: UpdateSchemaIdByTypeDto })
@ApiOperation({
summary: 'Update schemaId in CredentialsType',
description: 'This call provides the capability to update mapping between schema and type.'
description:
'This call provides the capability to update mapping between schema and type.',
})
@ApiResponse({
status: HttpStatus.OK,
......@@ -1199,7 +1227,7 @@ export default class AttestationController {
},
},
})
async updateSchemaIdByType(
public async updateSchemaIdByType(
@Body() body: { schemaId: string },
@Query() query: { type: string },
) {
......@@ -1213,8 +1241,11 @@ export default class AttestationController {
),
};
return res;
} catch (error: any) {
if (error.code === PrismaErrorCode.RECORD_NOT_FOUND) {
} catch (error: unknown) {
if (
error instanceof Prisma.PrismaClientKnownRequestError &&
error.code === PrismaErrorCode.RECORD_NOT_FOUND
) {
throw new NotFoundException(error.message);
}
throw new InternalServerErrorException(error);
......@@ -1224,7 +1255,8 @@ export default class AttestationController {
@Post('credentialType')
@ApiOperation({
summary: 'Create new CredentialType',
description: 'This call provides the capability to create mapping between schema and type.'
description:
'This call provides the capability to create mapping between schema and type.',
})
@ApiBody({ type: CredentialTypeDto })
@ApiResponse({
......@@ -1268,7 +1300,7 @@ export default class AttestationController {
},
},
})
async createCredentialType(@Body() body: CredentialTypeDto) {
public async createCredentialType(@Body() body: CredentialTypeDto) {
try {
const res: ResponseType = {
statusCode: HttpStatus.CREATED,
......@@ -1284,14 +1316,14 @@ export default class AttestationController {
@MessagePattern({
endpoint: `${NATSServices.SERVICE_NAME}/getIssueCredentials`,
})
async getIssueCredentials(data: GetIssueCredentialsDto) {
public async getIssueCredentials(data: GetIssueCredentialsDto) {
return this.attestationService.getIssueCredentials(data);
}
@MessagePattern({
endpoint: `${NATSServices.SERVICE_NAME}/getCredentialsTypeDetails`,
})
async getCredentialsTypeDetails(data: { type: string }) {
public async getCredentialsTypeDetails(data: { type: string }) {
let res;
const credentialsType =
......@@ -1320,7 +1352,8 @@ export default class AttestationController {
@Get('credentialType')
@ApiOperation({
summary: 'Fetch CredentialType contains schemaId and attributes by type',
description: 'This call provides the capability to get schema id and its attributes by provided type'
description:
'This call provides the capability to get schema id and its attributes by provided type',
})
@ApiQuery({ name: 'type', required: true })
@ApiResponse({
......@@ -1387,7 +1420,7 @@ export default class AttestationController {
},
},
})
async getCredentialTypeAttributes(@Query() query: { type: string }) {
public async getCredentialTypeAttributes(@Query() query: { type: string }) {
let res;
const credentialsType =
......@@ -1400,9 +1433,10 @@ export default class AttestationController {
version: string;
attrNames: string[];
seqNo: number;
} = await this.attestationService.getSchemaAndAttributesBySchemaIDFromLedger(
credentialsType.schemaId,
);
} =
await this.attestationService.getSchemaAndAttributesBySchemaIDFromLedger(
credentialsType.schemaId,
);
res = {
schema: {
schemaID: credentialsType?.schemaId,
......
......@@ -3,35 +3,35 @@ import { IsString, IsNotEmpty } from 'class-validator';
export default class CredentialDto {
@IsString()
@IsNotEmpty()
credentialId: string;
public credentialId: string;
@IsString()
@IsNotEmpty()
credDefId: string;
public credDefId: string;
@IsString()
schemaId?: string;
public schemaId?: string;
@IsString()
@IsNotEmpty()
participantId?: string;
public participantId?: string;
@IsString()
@IsNotEmpty()
principalDid?: string;
public principalDid?: string;
@IsString()
@IsNotEmpty()
state: string;
public state: string;
@IsString()
@IsNotEmpty()
threadId: string;
public threadId: string;
@IsString()
@IsNotEmpty()
connectionId: string;
public connectionId: string;
@IsString()
expirationDate?: Date | null;
public expirationDate?: Date | null;
}