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
Commits on Source (24)
Showing
with 1021 additions and 64 deletions
......@@ -24,15 +24,13 @@
"test:e2e": "jest --config ./test/jest.config.js"
},
"dependencies": {
"@nestjs/axios": "^3.0.1",
"@nestjs/common": "^10.2.10",
"@nestjs/config": "^3.1.1",
"@nestjs/core": "^10.2.10",
"@nestjs/microservices": "^10.2.10",
"@nestjs/platform-express": "^10.2.8",
"@nestjs/swagger": "^7.1.16",
"@nestjs/terminus": "^10.1.1",
"axios": "^1.6.2",
"@ocm/shared": "workspace:*",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"express": "^4.17.3",
......
import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { Application } from '../application.js';
describe('Application', () => {
let app: INestApplication;
beforeAll(async () => {
const moduleFixture = await Test.createTestingModule({
imports: [Application],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
afterAll(async () => {
await app.close();
});
it('should be defined', () => {
expect(app).toBeDefined();
});
});
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { httpConfig } from './config/http.config.js';
import { natsConfig } from './config/nats.config.js';
import { ssiConfig } from './config/ssi.config.js';
import { validationSchema } from './config/validation.js';
import { HealthModule } from './health/health.module.js';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [httpConfig, natsConfig, ssiConfig],
cache: true,
expandVariables: true,
validationSchema,
validationOptions: {
allowUnknown: true,
abortEarly: true,
},
}),
HealthModule,
],
})
export default class AppModule {}
import type { ConfigType } from '@nestjs/config';
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { RouterModule } from '@nestjs/core';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { HealthModule } from '@ocm/shared';
import { NATS_CLIENT } from './common/constants.js';
import { httpConfig } from './config/http.config.js';
import { natsConfig } from './config/nats.config.js';
import { ssiConfig } from './config/ssi.config.js';
import { validationSchema } from './config/validation.js';
import { CredentialOffersModule } from './credential-offers/credential-offers.module.js';
import { CredentialRequestsModule } from './credential-requests/credential-requests.module.js';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [httpConfig, natsConfig, ssiConfig],
cache: true,
expandVariables: true,
validationSchema,
validationOptions: {
allowUnknown: true,
abortEarly: true,
},
}),
ClientsModule.registerAsync({
isGlobal: true,
clients: [
{
name: NATS_CLIENT,
inject: [natsConfig.KEY],
useFactory: (config: ConfigType<typeof natsConfig>) => ({
transport: Transport.NATS,
options: {
url: config.url as string,
},
}),
},
],
}),
HealthModule.registerAsync({
inject: [natsConfig.KEY],
useFactory: (config: ConfigType<typeof natsConfig>) => {
const options: Parameters<typeof HealthModule.register>[0] = {};
if (config.monitoringUrl) {
options.nats = {
monitoringUrl: config.monitoringUrl as string,
};
}
return options;
},
}),
CredentialOffersModule,
CredentialRequestsModule,
RouterModule.register([
{ module: HealthModule, path: '/health' },
{ module: CredentialOffersModule, path: '/credential-offers' },
{ module: CredentialRequestsModule, path: '/credential-requests' },
]),
],
})
export class Application {}
export const SERVICE_NAME = 'CREDENTIAL_MANAGER_SERVICE';
export const NATS_CLIENT = Symbol('NATS_CLIENT');
import type { TestingModule } from '@nestjs/testing';
import type {
EventAnonCredsCredentialOfferGetAll,
EventAnonCredsCredentialOfferGetById,
} from '@ocm/shared';
import { Test } from '@nestjs/testing';
import { Subject, of, takeUntil } from 'rxjs';
import { NATS_CLIENT } from '../../common/constants.js';
import { CredentialOffersController } from '../credential-offers.controller.js';
import { CredentialOffersService } from '../credential-offers.service.js';
describe('CredentialOffersController', () => {
const natsClientMock = {};
let controller: CredentialOffersController;
let service: CredentialOffersService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [CredentialOffersController],
providers: [
{ provide: NATS_CLIENT, useValue: natsClientMock },
CredentialOffersService,
],
}).compile();
controller = module.get<CredentialOffersController>(
CredentialOffersController,
);
service = module.get<CredentialOffersService>(CredentialOffersService);
});
describe('find', () => {
it('should return a list of credential offers', (done) => {
const unsubscribe$ = new Subject<void>();
const tenantId = 'exampleTenantId';
const expectedResult: EventAnonCredsCredentialOfferGetAll['data'] = [];
jest
.spyOn(service, 'findCredentialOffers')
.mockReturnValueOnce(of(expectedResult));
controller
.find({ tenantId })
.pipe(takeUntil(unsubscribe$))
.subscribe((result) => {
expect(result).toStrictEqual(expectedResult);
unsubscribe$.next();
unsubscribe$.complete();
done();
});
});
});
describe('getById', () => {
it('should return a credential offer', (done) => {
const unsubscribe$ = new Subject<void>();
const tenantId = 'exampleTenantId';
const credentialOfferId = 'exampleCredentialOfferId';
const expectedResult: EventAnonCredsCredentialOfferGetById['data'] = {
cred_def_id: 'exampleCredDefId',
key_correctness_proof: {},
nonce: 'exampleNonce',
schema_id: 'exampleSchemaId',
};
jest
.spyOn(service, 'getCredentialOfferById')
.mockReturnValueOnce(of(expectedResult));
controller
.getById({ credentialOfferId }, { tenantId })
.pipe(takeUntil(unsubscribe$))
.subscribe((result) => {
expect(result).toStrictEqual(expectedResult);
unsubscribe$.next();
unsubscribe$.complete();
done();
});
});
});
});
import { ClientsModule } from '@nestjs/microservices';
import { Test } from '@nestjs/testing';
import { NATS_CLIENT } from '../../common/constants.js';
import { CredentialOffersController } from '../credential-offers.controller.js';
import { CredentialOffersModule } from '../credential-offers.module.js';
import { CredentialOffersService } from '../credential-offers.service.js';
describe('CredentialOffersModule', () => {
let credentialOffersController: CredentialOffersController;
let credentialOffersService: CredentialOffersService;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
imports: [
ClientsModule.registerAsync({
isGlobal: true,
clients: [{ name: NATS_CLIENT, useFactory: () => ({}) }],
}),
CredentialOffersModule,
],
}).compile();
credentialOffersController = moduleRef.get<CredentialOffersController>(
CredentialOffersController,
);
credentialOffersService = moduleRef.get<CredentialOffersService>(
CredentialOffersService,
);
});
it('should be defined', () => {
expect(credentialOffersController).toBeDefined();
expect(credentialOffersController).toBeInstanceOf(
CredentialOffersController,
);
expect(credentialOffersService).toBeDefined();
expect(credentialOffersService).toBeInstanceOf(CredentialOffersService);
});
});
import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing';
import {
EventAnonCredsCredentialOfferGetAll,
EventAnonCredsCredentialOfferGetById,
} from '@ocm/shared';
import { Subject, of, takeUntil } from 'rxjs';
import { NATS_CLIENT } from '../../common/constants.js';
import { CredentialOffersService } from '../credential-offers.service.js';
describe('CredentialOffersService', () => {
const natsClientMock = { send: jest.fn() };
let service: CredentialOffersService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
{ provide: NATS_CLIENT, useValue: natsClientMock },
CredentialOffersService,
],
}).compile();
service = module.get<CredentialOffersService>(CredentialOffersService);
});
describe('findCredentialOffers', () => {
it('should call natsClient.send with the correct arguments', (done) => {
const unsubscribe$ = new Subject<void>();
const tenantId = 'tenantId';
const expectedResult: EventAnonCredsCredentialOfferGetAll['data'] = [];
natsClientMock.send.mockReturnValueOnce(
of(new EventAnonCredsCredentialOfferGetAll(expectedResult, tenantId)),
);
service
.findCredentialOffers(tenantId)
.pipe(takeUntil(unsubscribe$))
.subscribe((result) => {
expect(natsClientMock.send).toHaveBeenCalledWith(
EventAnonCredsCredentialOfferGetAll.token,
{ tenantId },
);
expect(result).toStrictEqual(expectedResult);
unsubscribe$.next();
unsubscribe$.complete();
done();
});
});
});
describe('getCredentialOfferById', () => {
it('should call natsClient.send with the correct arguments', (done) => {
const unsubscribe$ = new Subject<void>();
const tenantId = 'tenantId';
const credentialOfferId = 'id';
const expectedResult: EventAnonCredsCredentialOfferGetById['data'] = {
cred_def_id: 'exampleCredDefId',
key_correctness_proof: {},
nonce: 'exampleNonce',
schema_id: 'exampleSchemaId',
};
natsClientMock.send.mockReturnValueOnce(
of(new EventAnonCredsCredentialOfferGetById(expectedResult, tenantId)),
);
service
.getCredentialOfferById(tenantId, credentialOfferId)
.pipe(takeUntil(unsubscribe$))
.subscribe((result) => {
expect(natsClientMock.send).toHaveBeenCalledWith(
EventAnonCredsCredentialOfferGetById.token,
{ tenantId, credentialOfferId },
);
expect(result).toStrictEqual(expectedResult);
unsubscribe$.next();
unsubscribe$.complete();
done();
});
});
});
});
import {
Controller,
Get,
HttpStatus,
Param,
Query,
UseInterceptors,
UsePipes,
ValidationPipe,
} from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { MultitenancyParams, ResponseFormatInterceptor } from '@ocm/shared';
import { CredentialOffersService } from './credential-offers.service.js';
import { GetByIdParams } from './dto/get-by-id.dto.js';
@Controller()
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
@UseInterceptors(ResponseFormatInterceptor)
@ApiTags('Credential Offers')
export class CredentialOffersController {
public constructor(private readonly service: CredentialOffersService) {}
@Get()
@ApiOperation({
summary: 'Fetch a list of credential offers',
description:
'This call provides a list of credential offers for a given tenant',
})
@ApiResponse({
status: HttpStatus.OK,
description: 'Credential offers fetched successfully',
content: {
'application/json': {
schema: {},
examples: {
'Credential offers fetched successfully': {
value: {
statusCode: 200,
message: 'Credential offers fetched successfully',
data: [
{
id: '71b784a3',
},
],
},
},
},
},
},
})
@ApiResponse({
status: HttpStatus.NOT_FOUND,
content: {
'application/json': {
schema: {},
examples: {
'Credential offer not found': {
value: {
statusCode: 404,
message: 'Credential offer not found',
data: null,
},
},
'Tenant not found': {
value: {
statusCode: 404,
message: 'Tenant not found',
data: null,
},
},
},
},
},
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: 'Something went wrong',
content: {
'application/json': {
schema: {},
examples: {
'Something went wrong': {
value: {
statusCode: 500,
message: 'Something went wrong',
error: 'Internal Server Error',
},
},
},
},
},
})
public find(@Query() { tenantId }: MultitenancyParams) {
return this.service.findCredentialOffers(tenantId);
}
@Get(':credentialOfferId')
@ApiOperation({
summary: 'Fetch a credential offer by ID',
description: 'This call provides a credential offer for a given ID',
})
@ApiResponse({
status: HttpStatus.OK,
description: 'Credential offer fetched successfully',
content: {
'application/json': {
schema: {},
examples: {
'Credential offer fetched successfully': {
value: {
statusCode: 200,
message: 'Credential offer fetched successfully',
data: {
id: '71b784a3',
},
},
},
},
},
},
})
@ApiResponse({
status: HttpStatus.NOT_FOUND,
content: {
'application/json': {
schema: {},
examples: {
'Credential offer not found': {
value: {
statusCode: 404,
message: 'Credential offer not found',
data: null,
},
},
'Tenant not found': {
value: {
statusCode: 404,
message: 'Tenant not found',
data: null,
},
},
},
},
},
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: 'Something went wrong',
content: {
'application/json': {
schema: {},
examples: {
'Something went wrong': {
value: {
statusCode: 500,
message: 'Something went wrong',
error: 'Internal Server Error',
},
},
},
},
},
})
public getById(
@Param() { credentialOfferId }: GetByIdParams,
@Query() { tenantId }: MultitenancyParams,
) {
return this.service.getCredentialOfferById(tenantId, credentialOfferId);
}
}
import { Module } from '@nestjs/common';
import { CredentialOffersController } from './credential-offers.controller.js';
import { CredentialOffersService } from './credential-offers.service.js';
@Module({
providers: [CredentialOffersService],
controllers: [CredentialOffersController],
})
export class CredentialOffersModule {}
import type {
EventAnonCredsCredentialOfferGetAllInput,
EventAnonCredsCredentialOfferGetByIdInput,
} from '@ocm/shared';
import { Inject, Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import {
EventAnonCredsCredentialOfferGetAll,
EventAnonCredsCredentialOfferGetById,
} from '@ocm/shared';
import { map } from 'rxjs';
import { NATS_CLIENT } from '../common/constants.js';
@Injectable()
export class CredentialOffersService {
public constructor(
@Inject(NATS_CLIENT) private readonly natsClient: ClientProxy,
) {}
public findCredentialOffers(tenantId: string) {
return this.natsClient
.send<
EventAnonCredsCredentialOfferGetAll,
EventAnonCredsCredentialOfferGetAllInput
>(EventAnonCredsCredentialOfferGetAll.token, { tenantId })
.pipe(map(({ data }) => data));
}
public getCredentialOfferById(tenantId: string, credentialOfferId: string) {
return this.natsClient
.send<
EventAnonCredsCredentialOfferGetById,
EventAnonCredsCredentialOfferGetByIdInput
>(EventAnonCredsCredentialOfferGetById.token, {
tenantId,
credentialOfferId,
})
.pipe(map(({ data }) => data));
}
}
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsString } from 'class-validator';
export class GetByIdParams {
@IsString()
@IsNotEmpty()
@ApiProperty({
description: 'The credential offer ID to retrieve',
format: 'string',
})
public credentialOfferId: string;
}
import type { TestingModule } from '@nestjs/testing';
import type {
EventAnonCredsCredentialRequestGetAll,
EventAnonCredsCredentialRequestGetById,
} from '@ocm/shared';
import { Test } from '@nestjs/testing';
import { Subject, of, takeUntil } from 'rxjs';
import { NATS_CLIENT } from '../../common/constants.js';
import { CredentialRequestsController } from '../credential-requests.controller.js';
import { CredentialRequestsService } from '../credential-requests.service.js';
describe('CredentialRequestsController', () => {
const natsClientMock = {};
let controller: CredentialRequestsController;
let service: CredentialRequestsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [CredentialRequestsController],
providers: [
{ provide: NATS_CLIENT, useValue: natsClientMock },
CredentialRequestsService,
],
}).compile();
controller = module.get<CredentialRequestsController>(
CredentialRequestsController,
);
service = module.get<CredentialRequestsService>(CredentialRequestsService);
});
describe('find', () => {
it('should return a list of credential requests', (done) => {
const unsubscribe$ = new Subject<void>();
const tenantId = 'exampleTenantId';
const expectedResult: EventAnonCredsCredentialRequestGetAll['data'] = [];
jest
.spyOn(service, 'findCredentialRequests')
.mockReturnValueOnce(of(expectedResult));
controller
.find({ tenantId })
.pipe(takeUntil(unsubscribe$))
.subscribe((result) => {
expect(result).toStrictEqual(expectedResult);
unsubscribe$.next();
unsubscribe$.complete();
done();
});
});
});
describe('getById', () => {
it('should return a credential request', (done) => {
const unsubscribe$ = new Subject<void>();
const tenantId = 'exampleTenantId';
const credentialRequestId = 'exampleCredentialRequestId';
const expectedResult: EventAnonCredsCredentialRequestGetById['data'] = {
blinded_ms: {},
blinded_ms_correctness_proof: {},
cred_def_id: 'cred_def_id',
nonce: 'nonce',
entropy: 'entropy',
prover_did: 'prover_did',
};
jest
.spyOn(service, 'getCredentialRequestById')
.mockReturnValueOnce(of(expectedResult));
controller
.getById({ credentialRequestId }, { tenantId })
.pipe(takeUntil(unsubscribe$))
.subscribe((result) => {
expect(result).toStrictEqual(expectedResult);
unsubscribe$.next();
unsubscribe$.complete();
done();
});
});
});
});
import { ClientsModule } from '@nestjs/microservices';
import { Test } from '@nestjs/testing';
import { NATS_CLIENT } from '../../common/constants.js';
import { CredentialRequestsController } from '../credential-requests.controller.js';
import { CredentialRequestsModule } from '../credential-requests.module.js';
import { CredentialRequestsService } from '../credential-requests.service.js';
describe('CredentialRequestsModule', () => {
let credentialRequestsController: CredentialRequestsController;
let credentialRequestsService: CredentialRequestsService;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
imports: [
ClientsModule.registerAsync({
isGlobal: true,
clients: [{ name: NATS_CLIENT, useFactory: () => ({}) }],
}),
CredentialRequestsModule,
],
}).compile();
credentialRequestsController = moduleRef.get<CredentialRequestsController>(
CredentialRequestsController,
);
credentialRequestsService = moduleRef.get<CredentialRequestsService>(
CredentialRequestsService,
);
});
it('should be defined', () => {
expect(credentialRequestsController).toBeDefined();
expect(credentialRequestsController).toBeInstanceOf(
CredentialRequestsController,
);
expect(credentialRequestsService).toBeDefined();
expect(credentialRequestsService).toBeInstanceOf(CredentialRequestsService);
});
});
import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing';
import { EventAnonCredsCredentialRequestGetAll } from '@ocm/shared';
import { Subject, of, takeUntil } from 'rxjs';
import { NATS_CLIENT } from '../../common/constants.js';
import { CredentialRequestsService } from '../credential-requests.service.js';
describe('CredentialRequestsService', () => {
const natsClientMock = { send: jest.fn() };
let service: CredentialRequestsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
{ provide: NATS_CLIENT, useValue: natsClientMock },
CredentialRequestsService,
],
}).compile();
service = module.get<CredentialRequestsService>(CredentialRequestsService);
});
describe('findCredentialRequests', () => {
it('should call the natsClient send method with the correct arguments', (done) => {
const unsubscribe$ = new Subject<void>();
const tenantId = 'tenantId';
const expectedResult: EventAnonCredsCredentialRequestGetAll['data'] = [];
natsClientMock.send.mockReturnValueOnce(
of(new EventAnonCredsCredentialRequestGetAll(expectedResult, tenantId)),
);
service
.findCredentialRequests(tenantId)
.pipe(takeUntil(unsubscribe$))
.subscribe((result) => {
expect(natsClientMock.send).toHaveBeenCalledWith(
EventAnonCredsCredentialRequestGetAll.token,
{ tenantId },
);
expect(result).toStrictEqual(expectedResult);
unsubscribe$.next();
unsubscribe$.complete();
done();
});
});
});
describe('getCredentialRequestById', () => {
it('should call the natsClient send method with the correct arguments', (done) => {
const unsubscribe$ = new Subject<void>();
const tenantId = 'tenantId';
const credentialRequestId = 'credentialRequestId';
const expectedResult: EventAnonCredsCredentialRequestGetAll['data'] = [];
natsClientMock.send.mockReturnValueOnce(
of(new EventAnonCredsCredentialRequestGetAll(expectedResult, tenantId)),
);
service
.getCredentialRequestById(tenantId, credentialRequestId)
.pipe(takeUntil(unsubscribe$))
.subscribe((result) => {
expect(natsClientMock.send).toHaveBeenCalledWith(
EventAnonCredsCredentialRequestGetAll.token,
{ tenantId, credentialRequestId },
);
expect(result).toStrictEqual(expectedResult);
unsubscribe$.next();
unsubscribe$.complete();
done();
});
});
});
});
import {
Controller,
Get,
HttpStatus,
Param,
Query,
UseInterceptors,
UsePipes,
ValidationPipe,
} from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { MultitenancyParams, ResponseFormatInterceptor } from '@ocm/shared';
import { CredentialRequestsService } from './credential-requests.service.js';
import { GetByIdParams } from './dto/get-by-id.dto.js';
@Controller()
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
@UseInterceptors(ResponseFormatInterceptor)
@ApiTags('Credential Requests')
export class CredentialRequestsController {
public constructor(private readonly service: CredentialRequestsService) {}
@Get()
@ApiOperation({
summary: 'Fetch a list of credential requests',
description:
'This call provides a list of credential requests for a given tenant',
})
@ApiResponse({
status: HttpStatus.OK,
description: 'Credential requests fetched successfully',
content: {
'application/json': {
schema: {},
examples: {
'Credential requests fetched successfully': {
value: {
statusCode: 200,
message: 'Credential requests fetched successfully',
data: [
{
id: '71b784a3',
},
],
},
},
'Tenant not found': {
value: {
statusCode: 404,
message: 'Tenant not found',
data: null,
},
},
},
},
},
})
@ApiResponse({
status: HttpStatus.NOT_FOUND,
content: {
'application/json': {
schema: {},
examples: {
'Credential request not found': {
value: {
statusCode: 404,
message: 'Credential request not found',
data: null,
},
},
'Tenant not found': {
value: {
statusCode: 404,
message: 'Tenant not found',
data: null,
},
},
},
},
},
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: 'Internal server error',
content: {
'application/json': {
schema: {},
examples: {
'Internal server error': {
value: {
statusCode: 500,
message: 'Internal server error',
data: null,
},
},
},
},
},
})
public find(@Query() { tenantId }: MultitenancyParams) {
return this.service.findCredentialRequests(tenantId);
}
@Get(':id')
@ApiOperation({
summary: 'Fetch a credential request by id',
description:
'This call provides a credential request for a given tenant by id',
})
@ApiResponse({
status: HttpStatus.OK,
description: 'Credential request fetched successfully',
content: {
'application/json': {
schema: {},
examples: {
'Credential request fetched successfully': {
value: {
statusCode: 200,
message: 'Credential request fetched successfully',
data: {
id: '71b784a3',
},
},
},
'Tenant not found': {
value: {
statusCode: 404,
message: 'Tenant not found',
data: null,
},
},
},
},
},
})
@ApiResponse({
status: HttpStatus.NOT_FOUND,
content: {
'application/json': {
schema: {},
examples: {
'Credential request not found': {
value: {
statusCode: 404,
message: 'Credential request not found',
data: null,
},
},
'Tenant not found': {
value: {
statusCode: 404,
message: 'Tenant not found',
data: null,
},
},
},
},
},
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: 'Internal server error',
content: {
'application/json': {
schema: {},
examples: {
'Internal server error': {
value: {
statusCode: 500,
message: 'Internal server error',
data: null,
},
},
},
},
},
})
public getById(
@Param() { credentialRequestId }: GetByIdParams,
@Query() { tenantId }: MultitenancyParams,
) {
return this.service.getCredentialRequestById(tenantId, credentialRequestId);
}
}
import { Module } from '@nestjs/common';
import { CredentialRequestsController } from './credential-requests.controller.js';
import { CredentialRequestsService } from './credential-requests.service.js';
@Module({
providers: [CredentialRequestsService],
controllers: [CredentialRequestsController],
})
export class CredentialRequestsModule {}
import type {
EventAnonCredsCredentialRequestGetAllInput,
EventAnonCredsCredentialRequestGetById,
EventAnonCredsCredentialRequestGetByIdInput,
} from '@ocm/shared';
import { Inject, Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import { EventAnonCredsCredentialRequestGetAll } from '@ocm/shared';
import { map } from 'rxjs';
import { NATS_CLIENT } from '../common/constants.js';
@Injectable()
export class CredentialRequestsService {
public constructor(
@Inject(NATS_CLIENT) private readonly natsClient: ClientProxy,
) {}
public findCredentialRequests(tenantId: string) {
return this.natsClient
.send<
EventAnonCredsCredentialRequestGetAll,
EventAnonCredsCredentialRequestGetAllInput
>(EventAnonCredsCredentialRequestGetAll.token, { tenantId })
.pipe(map(({ data }) => data));
}
public getCredentialRequestById(
tenantId: string,
credentialRequestId: string,
) {
return this.natsClient
.send<
EventAnonCredsCredentialRequestGetById,
EventAnonCredsCredentialRequestGetByIdInput
>(EventAnonCredsCredentialRequestGetAll.token, {
tenantId,
credentialRequestId,
})
.pipe(map(({ data }) => data));
}
}
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsString } from 'class-validator';
export class GetByIdParams {
@IsString()
@IsNotEmpty()
@ApiProperty({
description: 'The credential request ID to retrieve',
format: 'string',
})
public credentialRequestId: string;
}
import type { HealthIndicatorFunction } from '@nestjs/terminus';
import { Controller, Get } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import {
HealthCheck,
HealthCheckService,
HttpHealthIndicator,
} from '@nestjs/terminus';
@Controller('health')
export class HealthController {
public constructor(
private readonly config: ConfigService,
private readonly health: HealthCheckService,
private readonly http: HttpHealthIndicator,
) {}
@Get()
@HealthCheck()
public check() {
const healthIndicators: HealthIndicatorFunction[] = [];
const natsMonitoringUrl = this.config.get('nats.monitoringUrl');
if (typeof natsMonitoringUrl === 'string') {
healthIndicators.push(() =>
this.http.pingCheck('nats', natsMonitoringUrl),
);
} else {
healthIndicators.push(() => ({ nats: { status: 'down' } }));
}
return this.health.check(healthIndicators);
}
}