diff --git a/CHANGELOG.md b/CHANGELOG.md index 722c680a5..7fe42255d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added a new endpoint to get all platforms (`GET api/v1/platforms`) + ### Changed - Lifted the asset profile identifier editing restriction for `MANUAL` data sources in the asset profile details dialog of the admin control panel diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index 5ec148558..89f52e1ea 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -37,6 +37,7 @@ import { AssetsModule } from './endpoints/assets/assets.module'; import { BenchmarksModule } from './endpoints/benchmarks/benchmarks.module'; import { GhostfolioModule } from './endpoints/data-providers/ghostfolio/ghostfolio.module'; import { MarketDataModule } from './endpoints/market-data/market-data.module'; +import { PlatformsModule } from './endpoints/platforms/platforms.module'; import { PublicModule } from './endpoints/public/public.module'; import { SitemapModule } from './endpoints/sitemap/sitemap.module'; import { TagsModule } from './endpoints/tags/tags.module'; @@ -95,6 +96,7 @@ import { UserModule } from './user/user.module'; MarketDataModule, OrderModule, PlatformModule, + PlatformsModule, PortfolioModule, PortfolioSnapshotQueueModule, PrismaModule, diff --git a/apps/api/src/app/endpoints/platforms/platforms.controller.ts b/apps/api/src/app/endpoints/platforms/platforms.controller.ts new file mode 100644 index 000000000..46303a3f8 --- /dev/null +++ b/apps/api/src/app/endpoints/platforms/platforms.controller.ts @@ -0,0 +1,22 @@ +import { PlatformService } from '@ghostfolio/api/app/platform/platform.service'; +import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; +import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; +import { PlatformsResponse } from '@ghostfolio/common/interfaces'; +import { permissions } from '@ghostfolio/common/permissions'; + +import { Controller, Get, UseGuards } from '@nestjs/common'; +import { AuthGuard } from '@nestjs/passport'; + +@Controller('platforms') +export class PlatformsController { + public constructor(private readonly platformService: PlatformService) {} + + @Get() + @HasPermission(permissions.readPlatforms) + @UseGuards(AuthGuard('jwt'), HasPermissionGuard) + public async getPlatforms(): Promise { + const platforms = await this.platformService.getPlatforms(); + + return { platforms }; + } +} diff --git a/apps/api/src/app/endpoints/platforms/platforms.module.ts b/apps/api/src/app/endpoints/platforms/platforms.module.ts new file mode 100644 index 000000000..21d0edf69 --- /dev/null +++ b/apps/api/src/app/endpoints/platforms/platforms.module.ts @@ -0,0 +1,11 @@ +import { PlatformModule } from '@ghostfolio/api/app/platform/platform.module'; + +import { Module } from '@nestjs/common'; + +import { PlatformsController } from './platforms.controller'; + +@Module({ + controllers: [PlatformsController], + imports: [PlatformModule] +}) +export class PlatformsModule {} diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts index 4b8e8009a..7cf93691c 100644 --- a/libs/common/src/lib/interfaces/index.ts +++ b/libs/common/src/lib/interfaces/index.ts @@ -68,6 +68,7 @@ import type { LookupResponse } from './responses/lookup-response.interface'; import type { MarketDataDetailsResponse } from './responses/market-data-details-response.interface'; import type { MarketDataOfMarketsResponse } from './responses/market-data-of-markets-response.interface'; import type { OAuthResponse } from './responses/oauth-response.interface'; +import type { PlatformsResponse } from './responses/platforms-response.interface'; import type { PortfolioDividendsResponse } from './responses/portfolio-dividends-response.interface'; import type { PortfolioHoldingResponse } from './responses/portfolio-holding-response.interface'; import type { PortfolioHoldingsResponse } from './responses/portfolio-holdings-response.interface'; @@ -158,6 +159,7 @@ export { MarketDataDetailsResponse, MarketDataOfMarketsResponse, OAuthResponse, + PlatformsResponse, PortfolioChart, PortfolioDetails, PortfolioDividendsResponse, diff --git a/libs/common/src/lib/interfaces/responses/platforms-response.interface.ts b/libs/common/src/lib/interfaces/responses/platforms-response.interface.ts new file mode 100644 index 000000000..552912d9d --- /dev/null +++ b/libs/common/src/lib/interfaces/responses/platforms-response.interface.ts @@ -0,0 +1,5 @@ +import { Platform } from '@prisma/client'; + +export interface PlatformsResponse { + platforms: Platform[]; +} diff --git a/libs/common/src/lib/permissions.ts b/libs/common/src/lib/permissions.ts index 3fd2bef8c..cb4eb175b 100644 --- a/libs/common/src/lib/permissions.ts +++ b/libs/common/src/lib/permissions.ts @@ -93,6 +93,7 @@ export function getPermissions(aRole: Role): string[] { permissions.readAiPrompt, permissions.readMarketData, permissions.readMarketDataOfOwnAssetProfile, + permissions.readPlatforms, permissions.readPlatformsWithAccountCount, permissions.readTags, permissions.readWatchlist, @@ -136,6 +137,7 @@ export function getPermissions(aRole: Role): string[] { permissions.deleteWatchlistItem, permissions.readAiPrompt, permissions.readMarketDataOfOwnAssetProfile, + permissions.readPlatforms, permissions.readWatchlist, permissions.updateAccount, permissions.updateAccess,