From 8e86a4d2b1c4ac538ffe0de501ee85e088b7b270 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 3 Oct 2026 17:12:31 +0200 Subject: [PATCH] Task/refactor transform data source in request interceptor (#8020) Refactoring --- .../api/src/helper/data-source.helper.spec.ts | 22 ++++++++ apps/api/src/helper/data-source.helper.ts | 28 +++++------ ...form-data-source-in-request.interceptor.ts | 50 +++++-------------- 3 files changed, 49 insertions(+), 51 deletions(-) diff --git a/apps/api/src/helper/data-source.helper.spec.ts b/apps/api/src/helper/data-source.helper.spec.ts index 02d979441e..3bfef82add 100644 --- a/apps/api/src/helper/data-source.helper.spec.ts +++ b/apps/api/src/helper/data-source.helper.spec.ts @@ -83,6 +83,28 @@ describe('DataSourceHelper', () => { }) ).toBeUndefined(); }); + + it('Decodes an encoded data source if the subscription is not enabled', () => { + expect( + transformDataSourceInRequest({ + configurationService: createConfigurationService({ + isSubscriptionEnabled: false + }), + dataSource: encodeDataSource(DataSource.COINGECKO) + }) + ).toBe(DataSource.COINGECKO); + }); + + it('Keeps the data source GHOSTFOLIO if the subscription is not enabled', () => { + expect( + transformDataSourceInRequest({ + configurationService: createConfigurationService({ + isSubscriptionEnabled: false + }), + dataSource: DataSource.GHOSTFOLIO + }) + ).toBe(DataSource.GHOSTFOLIO); + }); }); describe('transformDataSourceInResponse', () => { diff --git a/apps/api/src/helper/data-source.helper.ts b/apps/api/src/helper/data-source.helper.ts index 19a26816d9..fb0ded3f1f 100644 --- a/apps/api/src/helper/data-source.helper.ts +++ b/apps/api/src/helper/data-source.helper.ts @@ -48,6 +48,18 @@ function getGhostfolioDataSources({ : []; } +function getUnmaskedGhostfolioDataSource({ + dataSource, + ghostfolioDataSources +}: { + dataSource?: DataSource; + ghostfolioDataSources: string[]; +}) { + return dataSource === DataSource.GHOSTFOLIO && ghostfolioDataSources?.[0] + ? (ghostfolioDataSources[0] as DataSource) + : dataSource; +} + function hashDataSource(dataSource: DataSource) { return createHash('sha256').update(dataSource).digest('hex').slice(0, 8); } @@ -84,18 +96,6 @@ export function getMaskedGhostfolioDataSource({ : dataSource; } -export function getUnmaskedGhostfolioDataSource({ - dataSource, - ghostfolioDataSources -}: { - dataSource?: DataSource; - ghostfolioDataSources: string[]; -}) { - return dataSource === DataSource.GHOSTFOLIO && ghostfolioDataSources?.[0] - ? (ghostfolioDataSources[0] as DataSource) - : dataSource; -} - export function isDataGatheringSupported({ dataSource, scraperConfiguration @@ -118,8 +118,8 @@ export function isValidEncodedDataSource(encodedDataSource: string) { /** * Gives the data source of a request without a transformation: an encoded data - * source is decoded, and the mask of the Ghostfolio data provider is resolved - * (see the TransformDataSourceInRequestInterceptor) + * source is decoded, and the mask of the Ghostfolio data provider is resolved if + * the subscription is enabled (see the TransformDataSourceInRequestInterceptor) */ export function transformDataSourceInRequest({ configurationService, diff --git a/apps/api/src/interceptors/transform-data-source-in-request/transform-data-source-in-request.interceptor.ts b/apps/api/src/interceptors/transform-data-source-in-request/transform-data-source-in-request.interceptor.ts index 7b537cd523..569ffc60ef 100644 --- a/apps/api/src/interceptors/transform-data-source-in-request/transform-data-source-in-request.interceptor.ts +++ b/apps/api/src/interceptors/transform-data-source-in-request/transform-data-source-in-request.interceptor.ts @@ -1,6 +1,6 @@ import { decodeDataSource, - getUnmaskedGhostfolioDataSource + transformDataSourceInRequest } from '@ghostfolio/api/helper/data-source.helper'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; @@ -28,30 +28,19 @@ export class TransformDataSourceInRequestInterceptor< const http = context.switchToHttp(); const request = http.getRequest(); - if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) { - if (request.body?.activities) { - const ghostfolioDataSources = this.configurationService.get( - 'DATA_SOURCES_GHOSTFOLIO_DATA_PROVIDER' - ); - - request.body.activities = request.body.activities.map((activity) => { - if (DataSource[activity.dataSource]) { - return { - ...activity, - dataSource: getUnmaskedGhostfolioDataSource({ - ghostfolioDataSources, - dataSource: activity.dataSource - }) - }; - } else { - return { - ...activity, - dataSource: decodeDataSource(activity.dataSource) - }; - } - }); - } + if (request.body?.activities) { + request.body.activities = request.body.activities.map((activity) => { + return { + ...activity, + dataSource: transformDataSourceInRequest({ + configurationService: this.configurationService, + dataSource: activity.dataSource + }) + }; + }); + } + if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) { for (const type of ['body', 'params', 'query']) { const dataSourceValue = request[type]?.dataSource; @@ -68,19 +57,6 @@ export class TransformDataSourceInRequestInterceptor< }); } } - } else { - if (request.body?.activities) { - request.body.activities = request.body.activities.map((activity) => { - if (DataSource[activity.dataSource]) { - return activity; - } else { - return { - ...activity, - dataSource: decodeDataSource(activity.dataSource) - }; - } - }); - } } return next.handle();