From a5833566a8053dc3ae78573feba101626826cb98 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 May 2024 17:52:39 +0200 Subject: [PATCH 1/5] Feature/skip caching in portfolio calculator if active filters (#3348) * Skip caching if active filters * Update changelog --- CHANGELOG.md | 4 ++++ .../portfolio-calculator.factory.ts | 8 ++++++-- .../calculator/portfolio-calculator.ts | 20 ++++++++++++------- ...aln-buy-and-sell-in-two-activities.spec.ts | 1 + ...folio-calculator-baln-buy-and-sell.spec.ts | 1 + .../twr/portfolio-calculator-baln-buy.spec.ts | 1 + ...ator-btcusd-buy-and-sell-partially.spec.ts | 1 + .../twr/portfolio-calculator-fee.spec.ts | 1 + .../portfolio-calculator-googl-buy.spec.ts | 1 + .../twr/portfolio-calculator-item.spec.ts | 1 + .../portfolio-calculator-liability.spec.ts | 1 + ...-calculator-msft-buy-with-dividend.spec.ts | 1 + .../portfolio-calculator-no-orders.spec.ts | 1 + ...ulator-novn-buy-and-sell-partially.spec.ts | 1 + ...folio-calculator-novn-buy-and-sell.spec.ts | 1 + .../src/app/portfolio/portfolio.service.ts | 9 ++++++++- .../app/redis-cache/redis-cache.service.ts | 2 +- .../src/events/portfolio-changed.listener.ts | 4 +++- 18 files changed, 47 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f682d51db..50e732acb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added a form validation against the DTO in the platform management of the admin control panel - Added a form validation against the DTO in the tag management of the admin control panel +### Changed + +- Skipped the caching in the portfolio calculator if there are active filters (experimental) + ### Fixed - Fixed an issue in the calculation of the portfolio summary caused by future liabilities diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts index 4937f1008..762415d1e 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts @@ -32,6 +32,7 @@ export class PortfolioCalculatorFactory { calculationType, currency, dateRange = 'max', + hasFilters, isExperimentalFeatures = false, userId }: { @@ -40,9 +41,12 @@ export class PortfolioCalculatorFactory { calculationType: PerformanceCalculationType; currency: string; dateRange?: DateRange; + hasFilters: boolean; isExperimentalFeatures?: boolean; userId: string; }): PortfolioCalculator { + const useCache = !hasFilters && isExperimentalFeatures; + switch (calculationType) { case PerformanceCalculationType.MWR: return new MWRPortfolioCalculator({ @@ -50,7 +54,7 @@ export class PortfolioCalculatorFactory { activities, currency, dateRange, - isExperimentalFeatures, + useCache, userId, configurationService: this.configurationService, currentRateService: this.currentRateService, @@ -64,7 +68,7 @@ export class PortfolioCalculatorFactory { currency, currentRateService: this.currentRateService, dateRange, - isExperimentalFeatures, + useCache, userId, configurationService: this.configurationService, exchangeRateDataService: this.exchangeRateDataService, diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 568969603..e021eb2d4 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -56,14 +56,15 @@ export abstract class PortfolioCalculator { private currency: string; private currentRateService: CurrentRateService; private dataProviderInfos: DataProviderInfo[]; + private dateRange: DateRange; private endDate: Date; private exchangeRateDataService: ExchangeRateDataService; - private isExperimentalFeatures: boolean; private redisCacheService: RedisCacheService; private snapshot: PortfolioSnapshot; private snapshotPromise: Promise; private startDate: Date; private transactionPoints: TransactionPoint[]; + private useCache: boolean; private userId: string; public constructor({ @@ -74,8 +75,8 @@ export abstract class PortfolioCalculator { currentRateService, dateRange, exchangeRateDataService, - isExperimentalFeatures, redisCacheService, + useCache, userId }: { accountBalanceItems: HistoricalDataItem[]; @@ -85,16 +86,16 @@ export abstract class PortfolioCalculator { currentRateService: CurrentRateService; dateRange: DateRange; exchangeRateDataService: ExchangeRateDataService; - isExperimentalFeatures: boolean; redisCacheService: RedisCacheService; + useCache: boolean; userId: string; }) { this.accountBalanceItems = accountBalanceItems; this.configurationService = configurationService; this.currency = currency; this.currentRateService = currentRateService; + this.dateRange = dateRange; this.exchangeRateDataService = exchangeRateDataService; - this.isExperimentalFeatures = isExperimentalFeatures; this.activities = activities .map( @@ -129,6 +130,7 @@ export abstract class PortfolioCalculator { }); this.redisCacheService = redisCacheService; + this.useCache = useCache; this.userId = userId; const { endDate, startDate } = getInterval(dateRange); @@ -1047,11 +1049,13 @@ export abstract class PortfolioCalculator { } private async initialize() { - if (this.isExperimentalFeatures) { + if (this.useCache) { const startTimeTotal = performance.now(); const cachedSnapshot = await this.redisCacheService.get( - this.redisCacheService.getPortfolioSnapshotKey(this.userId) + this.redisCacheService.getPortfolioSnapshotKey({ + userId: this.userId + }) ); if (cachedSnapshot) { @@ -1074,7 +1078,9 @@ export abstract class PortfolioCalculator { ); this.redisCacheService.set( - this.redisCacheService.getPortfolioSnapshotKey(this.userId), + this.redisCacheService.getPortfolioSnapshotKey({ + userId: this.userId + }), JSON.stringify(this.snapshot), this.configurationService.get('CACHE_QUOTES_TTL') ); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts index 422cf8bff..340f16b87 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts @@ -123,6 +123,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts index dee8b2478..53ebdf19f 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -108,6 +108,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts index db8ce01b3..bab265887 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts @@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index 5a403eda1..eba5d4674 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -121,6 +121,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts index 97a77492b..88d7adb71 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts @@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'USD', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts index c916a381d..690f1eb51 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts @@ -106,6 +106,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts index bf212f80b..422d119b2 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts @@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'USD', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts index 3ae63c72a..d468e8e00 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts @@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'USD', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts index 6948b4dbd..094c6cc2e 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts @@ -121,6 +121,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'USD', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts index 1dd74d7e5..6bb432bfc 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts @@ -71,6 +71,7 @@ describe('PortfolioCalculator', () => { activities: [], calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index d4451503a..f65d2ba61 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -108,6 +108,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts index 7850fb2bd..902f710ee 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -108,6 +108,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 573c48a83..61906982b 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -277,9 +277,11 @@ export class PortfolioService { const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, + dateRange, userId, calculationType: PerformanceCalculationType.TWR, currency: this.request.user.Settings.settings.baseCurrency, + hasFilters: filters?.length > 0, isExperimentalFeatures: this.request.user.Settings.settings.isExperimentalFeatures }); @@ -358,6 +360,7 @@ export class PortfolioService { userId, calculationType: PerformanceCalculationType.TWR, currency: userCurrency, + hasFilters: filters?.length > 0, isExperimentalFeatures: this.request.user?.Settings.settings.isExperimentalFeatures }); @@ -660,6 +663,7 @@ export class PortfolioService { }), calculationType: PerformanceCalculationType.TWR, currency: userCurrency, + hasFilters: true, isExperimentalFeatures: this.request.user.Settings.settings.isExperimentalFeatures }); @@ -931,6 +935,7 @@ export class PortfolioService { userId, calculationType: PerformanceCalculationType.TWR, currency: this.request.user.Settings.settings.baseCurrency, + hasFilters: filters?.length > 0, isExperimentalFeatures: this.request.user.Settings.settings.isExperimentalFeatures }); @@ -1085,7 +1090,7 @@ export class PortfolioService { ) ); - const { endDate, startDate } = getInterval(dateRange); + const { endDate } = getInterval(dateRange); const { activities } = await this.orderService.getOrders({ endDate, @@ -1123,6 +1128,7 @@ export class PortfolioService { userId, calculationType: PerformanceCalculationType.TWR, currency: userCurrency, + hasFilters: filters?.length > 0, isExperimentalFeatures: this.request.user.Settings.settings.isExperimentalFeatures }); @@ -1220,6 +1226,7 @@ export class PortfolioService { userId, calculationType: PerformanceCalculationType.TWR, currency: this.request.user.Settings.settings.baseCurrency, + hasFilters: false, isExperimentalFeatures: this.request.user.Settings.settings.isExperimentalFeatures }); diff --git a/apps/api/src/app/redis-cache/redis-cache.service.ts b/apps/api/src/app/redis-cache/redis-cache.service.ts index a313eadf1..53b177b4f 100644 --- a/apps/api/src/app/redis-cache/redis-cache.service.ts +++ b/apps/api/src/app/redis-cache/redis-cache.service.ts @@ -24,7 +24,7 @@ export class RedisCacheService { return this.cache.get(key); } - public getPortfolioSnapshotKey(userId: string) { + public getPortfolioSnapshotKey({ userId }: { userId: string }) { return `portfolio-snapshot-${userId}`; } diff --git a/apps/api/src/events/portfolio-changed.listener.ts b/apps/api/src/events/portfolio-changed.listener.ts index 0f8877127..4a6e3d386 100644 --- a/apps/api/src/events/portfolio-changed.listener.ts +++ b/apps/api/src/events/portfolio-changed.listener.ts @@ -17,7 +17,9 @@ export class PortfolioChangedListener { ); this.redisCacheService.remove( - this.redisCacheService.getPortfolioSnapshotKey(event.getUserId()) + this.redisCacheService.getPortfolioSnapshotKey({ + userId: event.getUserId() + }) ); } } From 486de968a2130bf9d6ed880b43a018e553a61acf Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 May 2024 17:53:34 +0200 Subject: [PATCH 2/5] Bugfix/fix division by zero error in dividend yield calculation (#3354) * Handle division by zero * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/portfolio/portfolio.service.ts | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50e732acb..8b3bdbbac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed an issue in the calculation of the portfolio summary caused by future liabilities +- Fixed a division by zero error in the dividend yield calculation (experimental) ## 2.77.1 - 2024-04-27 diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 61906982b..10c09a21f 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -704,17 +704,19 @@ export class PortfolioService { const dividendYieldPercent = this.getAnnualizedPerformancePercent({ daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)), - netPerformancePercent: dividendInBaseCurrency.div( - timeWeightedInvestment - ) + netPerformancePercent: timeWeightedInvestment.eq(0) + ? new Big(0) + : dividendInBaseCurrency.div(timeWeightedInvestment) }); const dividendYieldPercentWithCurrencyEffect = this.getAnnualizedPerformancePercent({ daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)), - netPerformancePercent: dividendInBaseCurrency.div( - timeWeightedInvestmentWithCurrencyEffect - ) + netPerformancePercent: timeWeightedInvestmentWithCurrencyEffect.eq(0) + ? new Big(0) + : dividendInBaseCurrency.div( + timeWeightedInvestmentWithCurrencyEffect + ) }); const historicalData = await this.dataProviderService.getHistorical( From 4416ba0c88a141f8f06e74eea67217d17683fdae Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 May 2024 19:16:59 +0200 Subject: [PATCH 3/5] Feature/set performance column of holdings table to stick at end (#3353) * Set up stickyEnd in performance column * Update changelog --- CHANGELOG.md | 1 + libs/ui/src/lib/holdings-table/holdings-table.component.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b3bdbbac..5dc779dba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Set the performance column of the holdings table to stick at the end - Skipped the caching in the portfolio calculator if there are active filters (experimental) ### Fixed diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.html b/libs/ui/src/lib/holdings-table/holdings-table.component.html index 8c0bca20f..181b120a8 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.html +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -109,7 +109,7 @@ - + Date: Thu, 2 May 2024 20:31:20 +0200 Subject: [PATCH 4/5] Feature/improve inactive user role (#3360) * Improve inactive role * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/auth/jwt.strategy.ts | 27 ++++++++++++++++++++---- apps/api/src/app/user/user.controller.ts | 13 +----------- apps/client/src/app/core/auth.guard.ts | 7 +++--- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dc779dba..467738562 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Set the performance column of the holdings table to stick at the end - Skipped the caching in the portfolio calculator if there are active filters (experimental) +- Improved the `INACTIVE` user role ### Fixed diff --git a/apps/api/src/app/auth/jwt.strategy.ts b/apps/api/src/app/auth/jwt.strategy.ts index c7ce38986..a8ad8fd08 100644 --- a/apps/api/src/app/auth/jwt.strategy.ts +++ b/apps/api/src/app/auth/jwt.strategy.ts @@ -2,10 +2,12 @@ import { UserService } from '@ghostfolio/api/app/user/user.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { HEADER_KEY_TIMEZONE } from '@ghostfolio/common/config'; +import { hasRole } from '@ghostfolio/common/permissions'; -import { Injectable, UnauthorizedException } from '@nestjs/common'; +import { HttpException, Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import * as countriesAndTimezones from 'countries-and-timezones'; +import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { ExtractJwt, Strategy } from 'passport-jwt'; @Injectable() @@ -29,6 +31,13 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { if (user) { if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) { + if (hasRole(user, 'INACTIVE')) { + throw new HttpException( + getReasonPhrase(StatusCodes.TOO_MANY_REQUESTS), + StatusCodes.TOO_MANY_REQUESTS + ); + } + const country = countriesAndTimezones.getCountryForTimezone(timezone)?.id; @@ -45,10 +54,20 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { return user; } else { - throw ''; + throw new HttpException( + getReasonPhrase(StatusCodes.NOT_FOUND), + StatusCodes.NOT_FOUND + ); + } + } catch (error) { + if (error?.getStatus() === StatusCodes.TOO_MANY_REQUESTS) { + throw error; + } else { + throw new HttpException( + getReasonPhrase(StatusCodes.UNAUTHORIZED), + StatusCodes.UNAUTHORIZED + ); } - } catch (err) { - throw new UnauthorizedException('unauthorized', err.message); } } } diff --git a/apps/api/src/app/user/user.controller.ts b/apps/api/src/app/user/user.controller.ts index 14c545192..39e78dcdc 100644 --- a/apps/api/src/app/user/user.controller.ts +++ b/apps/api/src/app/user/user.controller.ts @@ -2,11 +2,7 @@ import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorat import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { PropertyService } from '@ghostfolio/api/services/property/property.service'; import { User, UserSettings } from '@ghostfolio/common/interfaces'; -import { - hasPermission, - hasRole, - permissions -} from '@ghostfolio/common/permissions'; +import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import type { RequestWithUser } from '@ghostfolio/common/types'; import { @@ -63,13 +59,6 @@ export class UserController { public async getUser( @Headers('accept-language') acceptLanguage: string ): Promise { - if (hasRole(this.request.user, 'INACTIVE')) { - throw new HttpException( - getReasonPhrase(StatusCodes.TOO_MANY_REQUESTS), - StatusCodes.TOO_MANY_REQUESTS - ); - } - return this.userService.getUser( this.request.user, acceptLanguage?.split(',')?.[0] diff --git a/apps/client/src/app/core/auth.guard.ts b/apps/client/src/app/core/auth.guard.ts index 52d1e14ab..ee5ed77cd 100644 --- a/apps/client/src/app/core/auth.guard.ts +++ b/apps/client/src/app/core/auth.guard.ts @@ -54,9 +54,10 @@ export class AuthGuard { this.router.navigate(['/' + $localize`register`]); resolve(false); } else if ( - AuthGuard.PUBLIC_PAGE_ROUTES.filter((publicPageRoute) => - state.url.startsWith(publicPageRoute) - )?.length > 0 + AuthGuard.PUBLIC_PAGE_ROUTES.filter((publicPageRoute) => { + const [, url] = state.url.split('/'); + return `/${url}` === publicPageRoute; + })?.length > 0 ) { resolve(true); return EMPTY; From d9c07456cd52acff1d906893eb6b6de1ff76ecc1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 May 2024 20:32:47 +0200 Subject: [PATCH 5/5] Release 2.78.0 (#3361) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 467738562..bc79a2ddf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.78.0 - 2024-05-02 ### Added diff --git a/package.json b/package.json index 35a66b550..e2bb13468 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.77.1", + "version": "2.78.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio",