|
|
@ -1,9 +1,6 @@ |
|
|
import { AdminService } from '@ghostfolio/api/app/admin/admin.service'; |
|
|
|
|
|
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service'; |
|
|
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service'; |
|
|
import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; |
|
|
import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; |
|
|
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; |
|
|
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; |
|
|
import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.interceptor'; |
|
|
|
|
|
import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor'; |
|
|
|
|
|
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; |
|
|
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; |
|
|
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; |
|
|
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; |
|
|
import { |
|
|
import { |
|
|
@ -14,10 +11,7 @@ import { |
|
|
} from '@ghostfolio/common/config'; |
|
|
} from '@ghostfolio/common/config'; |
|
|
import { UpdateBulkMarketDataDto } from '@ghostfolio/common/dtos'; |
|
|
import { UpdateBulkMarketDataDto } from '@ghostfolio/common/dtos'; |
|
|
import { getCurrencyFromSymbol, isCurrency } from '@ghostfolio/common/helper'; |
|
|
import { getCurrencyFromSymbol, isCurrency } from '@ghostfolio/common/helper'; |
|
|
import { |
|
|
import { MarketDataOfMarketsResponse } from '@ghostfolio/common/interfaces'; |
|
|
MarketDataDetailsResponse, |
|
|
|
|
|
MarketDataOfMarketsResponse |
|
|
|
|
|
} from '@ghostfolio/common/interfaces'; |
|
|
|
|
|
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; |
|
|
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; |
|
|
import { RequestWithUser } from '@ghostfolio/common/types'; |
|
|
import { RequestWithUser } from '@ghostfolio/common/types'; |
|
|
|
|
|
|
|
|
@ -30,8 +24,7 @@ import { |
|
|
Param, |
|
|
Param, |
|
|
Post, |
|
|
Post, |
|
|
Query, |
|
|
Query, |
|
|
UseGuards, |
|
|
UseGuards |
|
|
UseInterceptors |
|
|
|
|
|
} from '@nestjs/common'; |
|
|
} from '@nestjs/common'; |
|
|
import { REQUEST } from '@nestjs/core'; |
|
|
import { REQUEST } from '@nestjs/core'; |
|
|
import { AuthGuard } from '@nestjs/passport'; |
|
|
import { AuthGuard } from '@nestjs/passport'; |
|
|
@ -42,7 +35,6 @@ import { getReasonPhrase, StatusCodes } from 'http-status-codes'; |
|
|
@Controller('market-data') |
|
|
@Controller('market-data') |
|
|
export class MarketDataController { |
|
|
export class MarketDataController { |
|
|
public constructor( |
|
|
public constructor( |
|
|
private readonly adminService: AdminService, |
|
|
|
|
|
private readonly marketDataService: MarketDataService, |
|
|
private readonly marketDataService: MarketDataService, |
|
|
@Inject(REQUEST) private readonly request: RequestWithUser, |
|
|
@Inject(REQUEST) private readonly request: RequestWithUser, |
|
|
private readonly symbolProfileService: SymbolProfileService, |
|
|
private readonly symbolProfileService: SymbolProfileService, |
|
|
@ -87,49 +79,6 @@ export class MarketDataController { |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@Get(':dataSource/:symbol') |
|
|
|
|
|
@UseGuards(AuthGuard('jwt')) |
|
|
|
|
|
@UseInterceptors(TransformDataSourceInRequestInterceptor) |
|
|
|
|
|
@UseInterceptors(TransformDataSourceInResponseInterceptor) |
|
|
|
|
|
public async getMarketDataBySymbol( |
|
|
|
|
|
@Param('dataSource') dataSource: DataSource, |
|
|
|
|
|
@Param('symbol') symbol: string |
|
|
|
|
|
): Promise<MarketDataDetailsResponse> { |
|
|
|
|
|
const [assetProfile] = await this.symbolProfileService.getSymbolProfiles([ |
|
|
|
|
|
{ dataSource, symbol } |
|
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
|
|
if (!assetProfile && !isCurrency(getCurrencyFromSymbol(symbol))) { |
|
|
|
|
|
throw new HttpException( |
|
|
|
|
|
getReasonPhrase(StatusCodes.NOT_FOUND), |
|
|
|
|
|
StatusCodes.NOT_FOUND |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const canReadAllAssetProfiles = hasPermission( |
|
|
|
|
|
this.request.user.permissions, |
|
|
|
|
|
permissions.readMarketData |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
const canReadOwnAssetProfile = |
|
|
|
|
|
assetProfile?.userId === this.request.user.id && |
|
|
|
|
|
hasPermission( |
|
|
|
|
|
this.request.user.permissions, |
|
|
|
|
|
permissions.readMarketDataOfOwnAssetProfile |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
if (!canReadAllAssetProfiles && !canReadOwnAssetProfile) { |
|
|
|
|
|
throw new HttpException( |
|
|
|
|
|
assetProfile?.userId |
|
|
|
|
|
? getReasonPhrase(StatusCodes.NOT_FOUND) |
|
|
|
|
|
: getReasonPhrase(StatusCodes.FORBIDDEN), |
|
|
|
|
|
assetProfile?.userId ? StatusCodes.NOT_FOUND : StatusCodes.FORBIDDEN |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return this.adminService.getMarketDataBySymbol({ dataSource, symbol }); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Post(':dataSource/:symbol') |
|
|
@Post(':dataSource/:symbol') |
|
|
@UseGuards(AuthGuard('jwt')) |
|
|
@UseGuards(AuthGuard('jwt')) |
|
|
public async updateMarketData( |
|
|
public async updateMarketData( |
|
|
|