Skip to content

Commit 946ecd2

Browse files
pranalidhanavadesujitawKambleSahil3
authored
feat: platform admin and ecosystem (#1551)
* feat: ecosystem service and create ecosystem invitation API route (#1540) * feat/add script to add platform admin keycloak and role Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/eslint issue Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/coderabbit comments Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/changes to fetch value from db Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * feat: ecosystem service and create ecosystem invitation API route Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: coderabbit issues Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: coderabbit warnings Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * feat: get all invitations api Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * refactor: removed userId parameter from send invitation and get invitation api Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * feat: create and get ecosystem api routes Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: coderabbit warning Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: coderabbit warnings and suggestions Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: coderabbit warnings resolved Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: coderabbit issues Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * resolved comments on PR Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * resolve comments on PR Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * resolve comments on PR Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> --------- Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> Co-authored-by: sujitaw <sujit.sutar@ayanworks.com> * feat: Add script to add platform admin to keycloak and create user org roles (#1538) * feat/add script to add platform admin keycloak and role Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/eslint issue Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/coderabbit comments Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/changes to fetch value from db Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix pr comments Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix pr comments Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> --------- Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * feat: ecosystem member invitation and management API's (#1545) * feat/add script to add platform admin keycloak and role Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/eslint issue Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/coderabbit comments Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * feat: ecosystem service and create ecosystem invitation API route Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: coderabbit issues Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: coderabbit warnings Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * feat: get all invitations api Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * wip Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * wip completed invite member and update status for invitation Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * wip Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * wip Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * feat/added ecosystem invitation workflow apis Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/code rabbit comments Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/minor typo issue Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/ pr comments Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/pr comments Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> --------- Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> Co-authored-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix/version for nest-cli Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * feat: add dockerfile for ecosystem Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com> * feat: add ecosystemt in github actions workflow Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com> * feat: create intent API endpoints and intent template mapping APIs (#1547) * feat: create intent APIs Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * feat: create intent mapping and create intent APIs Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: sonarlint issues Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * refactor: move validations from ecosystem repository to ecosystem service Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: sonarlint issues Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: sonarlint issues Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: sonarlint issues Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: coderabbit suggestions Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: comments on PR Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> --------- Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: resloved issue for docker build (#1549) Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: Enable/disable ecosystem (#1550) * refactor: added isEcosystemEnabled flag in database in platform_config table Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * refactor: enable/disable ecosystem feature from database Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix: coderabbit suggestions Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * refactor: enable/disable ecosystem feature and delete intent API issue Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * comments on PR Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * coderabbit comments on PR Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> --------- Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> * fix/code rabbit issue Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> * fix/code rabbit issue Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> --------- Signed-off-by: sujitaw <sujit.sutar@ayanworks.com> Signed-off-by: pranalidhanavade <pranali.dhanavade@ayanworks.com> Signed-off-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com> Co-authored-by: sujitaw <sujit.sutar@ayanworks.com> Co-authored-by: sahil.kamble@ayanworks.com <sahil.kamble@ayanworks.com>
1 parent b3197dc commit 946ecd2

53 files changed

Lines changed: 5347 additions & 1045 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.sample

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ AGENT_SERVICE_NKEY_SEED=xxxxxxxxxxxxx // Please provide Nkeys secret for agent s
118118
VERIFICATION_NKEY_SEED=xxxxxxxxxxxxx // Please provide Nkeys secret for verification service
119119
ISSUANCE_NKEY_SEED=xxxxxxxxxxxxx // Please provide Nkeys secret for issuance service
120120
CONNECTION_NKEY_SEED=xxxxxxxxxxxxx // Please provide Nkeys secret for connection service
121+
ECOSYSTEM_NKEY_SEED=xxxxxxxxxxxxx // Please provide Nkeys secret for ecosystem service
121122
CREDENTAILDEFINITION_NKEY_SEED=xxxxxxxxxxxxx // Please provide Nkeys secret for credential-definition service
122123
SCHEMA_NKEY_SEED=xxxxxxxxxxxxx // Please provide Nkeys secret for schema service
123124
UTILITIES_NKEY_SEED=xxxxxxxxxxxxx // Please provide Nkeys secret for utilities service
@@ -203,6 +204,12 @@ CLUSTER_NAME=CREDO-CONTROLLER-CLUSTER # ECS cluster name for credo controller
203204
TASKDEFINITION_FAMILY=CREDO-CONTROLLER-TASKDEFINITION # ECS taskdefinition name for credo controller
204205
PROTOCOL=http
205206

207+
#Platform admin setup
208+
PLATFORM_ADMIN_KEYCLOAK_ID=adminClient #Create a new keycloak client for platform admin (admin console) with adminClient name and add its client id
209+
PLATFORM_ADMIN_KEYCLOAK_SECRET=xxxxxxxxxxxx #Add the secret of keycloak client created for the above platform admin (admin console) id
210+
PLATFORM_ADMIN_OLD_CLIENT_ID=adminClient #Add incase the keycloak id of the old platform client is changed and want to update all the users in database with the new admin client
211+
#Note : the above is for platform client and not platform admin client
212+
206213
# To add more client add the following variables for each additional client.
207214
# Replace the `CLIENT-NAME` with the appropriate client name as added in `SUPPORTED_SSO_CLIENTS`
208215
# Default client will not need the following details

.github/workflows/continuous-delivery.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ jobs:
3434
- x509
3535
- oid4vc-issuance
3636
- oid4vc-verification
37+
- ecosystem
3738

3839
permissions:
3940
contents: read

Dockerfiles/Dockerfile.ecosystem

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Stage 1: Build the application
2+
FROM node:18-alpine as build
3+
# Install OpenSSL
4+
RUN apk add --no-cache openssl
5+
RUN npm install -g pnpm
6+
# Set the working directory
7+
WORKDIR /app
8+
9+
# Copy package.json and package-lock.json
10+
COPY package.json ./
11+
COPY pnpm-workspace.yaml ./
12+
#COPY package-lock.json ./
13+
14+
ENV PUPPETEER_SKIP_DOWNLOAD=true
15+
16+
# Install dependencies while ignoring scripts (including Puppeteer's installation)
17+
RUN pnpm i --ignore-scripts
18+
19+
# Copy the rest of the application code
20+
COPY . .
21+
# RUN cd libs/prisma-service && npx prisma migrate deploy && npx prisma generate
22+
RUN cd libs/prisma-service && npx prisma generate
23+
24+
# Build the connection service
25+
RUN pnpm run build ecosystem
26+
27+
# Stage 2: Create the final image
28+
FROM node:18-alpine
29+
# Install OpenSSL
30+
RUN apk add --no-cache openssl
31+
# RUN npm install -g pnpm
32+
# Set the working directory
33+
WORKDIR /app
34+
35+
# Copy the compiled code from the build stage
36+
COPY --from=build /app/dist/apps/ecosystem/ ./dist/apps/ecosystem/
37+
38+
# Copy the libs folder from the build stage
39+
COPY --from=build /app/libs/ ./libs/
40+
#COPY --from=build /app/package.json ./
41+
COPY --from=build /app/node_modules ./node_modules
42+
43+
# Set the command to run the microservice
44+
CMD ["sh", "-c", "cd libs/prisma-service && npx prisma migrate deploy && npx prisma generate && cd ../.. && node dist/apps/ecosystem/main.js"]

apps/api-gateway/src/app.module.ts

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,41 @@
1+
import { ClientsModule, Transport } from '@nestjs/microservices';
2+
import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant';
3+
import { ConditionalModule, ConfigModule } from '@nestjs/config';
14
import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common';
5+
26
import { AgentController } from './agent/agent.controller';
37
import { AgentModule } from './agent-service/agent-service.module';
48
import { AppController } from './app.controller';
59
import { AppService } from './app.service';
610
import { AuthzMiddleware } from './authz/authz.middleware';
711
import { AuthzModule } from './authz/authz.module';
8-
import { ClientsModule, Transport } from '@nestjs/microservices';
9-
import { ConditionalModule, ConfigModule } from '@nestjs/config';
12+
import { CacheModule } from '@nestjs/cache-manager';
13+
import { CloudWalletModule } from './cloud-wallet/cloud-wallet.module';
14+
import { ConnectionModule } from './connection/connection.module';
15+
import { ContextModule } from '@credebl/context/contextModule';
1016
import { CredentialDefinitionModule } from './credential-definition/credential-definition.module';
17+
import { EcosystemModule } from './ecosystem/ecosystem.module';
18+
import { EcosystemSwaggerFilter } from './authz/guards/ecosystem-swagger.filter';
1119
import { FidoModule } from './fido/fido.module';
20+
import { GeoLocationModule } from './geo-location/geo-location.module';
21+
import { GlobalConfigModule } from '@credebl/config/global-config.module';
1222
import { IssuanceModule } from './issuance/issuance.module';
23+
import { LoggerModule } from '@credebl/logger/logger.module';
24+
import { NotificationModule } from './notification/notification.module';
25+
import { Oid4vcIssuanceModule } from './oid4vc-issuance/oid4vc-issuance.module';
26+
import { Oid4vpModule } from './oid4vc-verification/oid4vc-verification.module';
1327
import { OrganizationModule } from './organization/organization.module';
28+
import { ConfigModule as PlatformConfig } from '@credebl/config/config.module';
1429
import { PlatformModule } from './platform/platform.module';
15-
import { VerificationModule } from './verification/verification.module';
1630
import { RevocationController } from './revocation/revocation.controller';
1731
import { RevocationModule } from './revocation/revocation.module';
1832
import { SchemaModule } from './schema/schema.module';
1933
import { UserModule } from './user/user.module';
20-
import { ConnectionModule } from './connection/connection.module';
21-
import { getNatsOptions } from '@credebl/common/nats.config';
22-
import { CacheModule } from '@nestjs/cache-manager';
23-
import { WebhookModule } from './webhook/webhook.module';
2434
import { UtilitiesModule } from './utilities/utilities.module';
25-
import { NotificationModule } from './notification/notification.module';
26-
import { GeoLocationModule } from './geo-location/geo-location.module';
27-
import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant';
28-
import { CloudWalletModule } from './cloud-wallet/cloud-wallet.module';
29-
import { ContextModule } from '@credebl/context/contextModule';
30-
import { LoggerModule } from '@credebl/logger/logger.module';
31-
import { GlobalConfigModule } from '@credebl/config/global-config.module';
32-
import { ConfigModule as PlatformConfig } from '@credebl/config/config.module';
33-
import { Oid4vcIssuanceModule } from './oid4vc-issuance/oid4vc-issuance.module';
35+
import { VerificationModule } from './verification/verification.module';
36+
import { WebhookModule } from './webhook/webhook.module';
3437
import { X509Module } from './x509/x509.module';
35-
import { Oid4vpModule } from './oid4vc-verification/oid4vc-verification.module';
38+
import { getNatsOptions } from '@credebl/common/nats.config';
3639
import { shouldLoadOidcModules } from '@credebl/common/common.utils';
3740

3841
@Module({
@@ -63,6 +66,7 @@ import { shouldLoadOidcModules } from '@credebl/common/common.utils';
6366
UtilitiesModule,
6467
WebhookModule,
6568
NotificationModule,
69+
EcosystemModule,
6670
GlobalConfigModule,
6771
CacheModule.register(),
6872
GeoLocationModule,
@@ -74,6 +78,7 @@ import { shouldLoadOidcModules } from '@credebl/common/common.utils';
7478
controllers: [AppController],
7579
providers: [
7680
AppService,
81+
EcosystemSwaggerFilter,
7782
{
7883
provide: MICRO_SERVICE_NAME,
7984
useValue: 'APIGATEWAY'

apps/api-gateway/src/authz/authz.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { CommonConstants } from '@credebl/common/common.constant';
88
import { CommonModule } from '../../../../libs/common/src/common.module';
99
import { CommonService } from '../../../../libs/common/src/common.service';
1010
import { ConnectionService } from '../connection/connection.service';
11+
import { EcosystemModule } from '../ecosystem/ecosystem.module';
1112
import { HttpModule } from '@nestjs/axios';
1213
import { JwtStrategy } from './jwt.strategy';
1314
import { MobileJwtStrategy } from './mobile-jwt.strategy';
@@ -25,6 +26,7 @@ import { getNatsOptions } from '@credebl/common/nats.config';
2526

2627
@Module({
2728
imports: [
29+
EcosystemModule,
2830
HttpModule,
2931
PassportModule.register({
3032
defaultStrategy: 'jwt',
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { CanActivate, ForbiddenException, Injectable, Scope } from '@nestjs/common';
2+
3+
import { EcosystemRepository } from 'apps/ecosystem/repositories/ecosystem.repository';
4+
import { ResponseMessages } from '@credebl/common/response-messages';
5+
6+
@Injectable({ scope: Scope.REQUEST })
7+
export class EcosystemFeatureGuard implements CanActivate {
8+
constructor(private readonly ecosystemRepository: EcosystemRepository) {}
9+
10+
async canActivate(): Promise<boolean> {
11+
const config = await this.ecosystemRepository.getPlatformConfig();
12+
const enabled = Boolean(config?.isEcosystemEnabled);
13+
14+
if (!enabled) {
15+
throw new ForbiddenException(ResponseMessages.ecosystem.error.featureIsDisabled);
16+
}
17+
18+
return true;
19+
}
20+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import { BadRequestException, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';
2+
3+
import { Injectable } from '@nestjs/common';
4+
import { OrgRoles } from 'libs/org-roles/enums';
5+
import { ROLES_KEY } from '../decorators/roles.decorator';
6+
import { Reflector } from '@nestjs/core';
7+
import { ResponseMessages } from '@credebl/common/response-messages';
8+
import { validate as isValidUUID } from 'uuid';
9+
10+
@Injectable()
11+
export class EcosystemRolesGuard implements CanActivate {
12+
constructor(private readonly reflector: Reflector) {} // eslint-disable-next-line array-callback-return
13+
14+
async canActivate(context: ExecutionContext): Promise<boolean> {
15+
const requiredRoles = this.reflector.getAllAndOverride<OrgRoles[]>(ROLES_KEY, [
16+
context.getHandler(),
17+
context.getClass()
18+
]);
19+
20+
if (!requiredRoles || 0 === requiredRoles.length) {
21+
return true;
22+
}
23+
const requiredRolesNames = requiredRoles as string[];
24+
const reqData = context.switchToHttp().getRequest();
25+
const { user } = reqData;
26+
27+
let orgId = '';
28+
29+
switch (true) {
30+
case 'string' === typeof reqData.params?.orgId:
31+
orgId = reqData.params.orgId.trim();
32+
break;
33+
34+
case 'string' === typeof reqData.query?.orgId:
35+
orgId = reqData.query.orgId.trim();
36+
break;
37+
38+
case 'string' === typeof reqData.body?.orgId:
39+
orgId = reqData.body.orgId.trim();
40+
break;
41+
42+
default:
43+
orgId = '';
44+
}
45+
46+
const isPlatformAdmin = user.email === process.env.PLATFORM_ADMIN_EMAIL;
47+
48+
if (user?.ecosystemRoles && requiredRolesNames.some((role: string) => user.ecosystemRoles.includes(role))) {
49+
return true;
50+
}
51+
52+
if (isPlatformAdmin && requiredRolesNames.includes(OrgRoles.PLATFORM_ADMIN)) {
53+
// eslint-disable-next-line array-callback-return
54+
const isPlatformAdminFlag = user.userOrgRoles.find((orgDetails) => {
55+
if (orgDetails.orgRole.name === OrgRoles.PLATFORM_ADMIN) {
56+
return true;
57+
}
58+
});
59+
60+
if (isPlatformAdminFlag) {
61+
return true;
62+
}
63+
}
64+
65+
if (orgId) {
66+
if (!isValidUUID(orgId)) {
67+
throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId);
68+
}
69+
70+
if (user.hasOwnProperty('resource_access') && user.resource_access[orgId]) {
71+
const orgRoles: string[] = user.resource_access[orgId].roles;
72+
const roleAccess = requiredRoles.some((role) => orgRoles.includes(role));
73+
74+
if (!roleAccess) {
75+
throw new ForbiddenException(ResponseMessages.organisation.error.roleNotMatch, {
76+
cause: new Error('error'),
77+
description: ResponseMessages.errorMessages.forbidden
78+
});
79+
}
80+
return roleAccess;
81+
}
82+
83+
const specificOrg = user.userOrgRoles.find((orgDetails) => {
84+
if (!orgDetails.orgId) {
85+
return false;
86+
}
87+
return orgDetails.orgId.toString().trim() === orgId.toString().trim();
88+
});
89+
90+
if (!specificOrg) {
91+
throw new ForbiddenException(ResponseMessages.organisation.error.orgNotMatch, {
92+
cause: new Error('error'),
93+
description: ResponseMessages.errorMessages.forbidden
94+
});
95+
}
96+
97+
user.selectedOrg = specificOrg;
98+
// eslint-disable-next-line array-callback-return
99+
user.selectedOrg.orgRoles = user.userOrgRoles
100+
.filter((orgRoleItem) => orgRoleItem.orgId && orgRoleItem.orgId.toString().trim() === orgId.toString().trim())
101+
.map((orgRoleItem) => orgRoleItem.orgRole.name);
102+
} else {
103+
return false;
104+
}
105+
106+
// Sending user friendly message if a user attempts to access an API that is inaccessible to their role
107+
const roleAccess = requiredRoles.some((role) => user.selectedOrg?.orgRoles.includes(role));
108+
if (!roleAccess) {
109+
throw new ForbiddenException(ResponseMessages.organisation.error.roleNotMatch, {
110+
cause: new Error('error'),
111+
description: ResponseMessages.errorMessages.forbidden
112+
});
113+
}
114+
115+
return roleAccess;
116+
}
117+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { EcosystemRepository } from 'apps/ecosystem/repositories/ecosystem.repository';
2+
import { Injectable } from '@nestjs/common';
3+
import { OpenAPIObject } from '@nestjs/swagger';
4+
5+
@Injectable()
6+
export class EcosystemSwaggerFilter {
7+
constructor(private readonly ecosystemRepository: EcosystemRepository) {}
8+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
9+
async filterDocument(document: OpenAPIObject): Promise<OpenAPIObject> {
10+
const config = await this.ecosystemRepository.getPlatformConfig();
11+
const enabled = Boolean(config?.isEcosystemEnabled);
12+
13+
if (!enabled) {
14+
if (!document.paths) {
15+
return document;
16+
}
17+
Object.keys(document.paths).forEach((path) => {
18+
Object.keys(document.paths[path]).forEach((method) => {
19+
const operation = document.paths[path][method];
20+
21+
if (operation.tags?.includes('ecosystem')) {
22+
delete document.paths[path][method];
23+
}
24+
});
25+
26+
if (0 === Object.keys(document.paths[path]).length) {
27+
delete document.paths[path];
28+
}
29+
});
30+
}
31+
32+
return document;
33+
}
34+
}

0 commit comments

Comments
 (0)