From 5284f5ec77a6548dbd76c2503b418b9067577d88 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 13 Jul 2026 19:36:18 +0200 Subject: [PATCH] Task/harden validation of countries in asset profile endpoints (#7316) * Harden validation of countries * Update changelog --- CHANGELOG.md | 1 + libs/common/src/lib/dtos/country.dto.ts | 11 +++++++++++ libs/common/src/lib/dtos/create-asset-profile.dto.ts | 8 +++++++- libs/common/src/lib/dtos/index.ts | 2 ++ libs/common/src/lib/dtos/update-asset-profile.dto.ts | 8 +++++++- 5 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 libs/common/src/lib/dtos/country.dto.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 83146cce0..270ea6f09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Hardened the validation of the countries in the asset profile endpoints - Set the change detection strategy to `OnPush` in the _X-ray_ page ## 3.25.0 - 2026-07-12 diff --git a/libs/common/src/lib/dtos/country.dto.ts b/libs/common/src/lib/dtos/country.dto.ts new file mode 100644 index 000000000..663aa1ac6 --- /dev/null +++ b/libs/common/src/lib/dtos/country.dto.ts @@ -0,0 +1,11 @@ +import { IsISO31661Alpha2, IsNumber, Max, Min } from 'class-validator'; + +export class CountryDto { + @IsISO31661Alpha2() + code: string; + + @IsNumber() + @Min(0) + @Max(1) + weight: number; +} diff --git a/libs/common/src/lib/dtos/create-asset-profile.dto.ts b/libs/common/src/lib/dtos/create-asset-profile.dto.ts index 73f0d3f5a..3e7e2224e 100644 --- a/libs/common/src/lib/dtos/create-asset-profile.dto.ts +++ b/libs/common/src/lib/dtos/create-asset-profile.dto.ts @@ -1,15 +1,19 @@ import { IsCurrencyCode } from '@ghostfolio/common/validators/is-currency-code'; import { AssetClass, AssetSubClass, DataSource, Prisma } from '@prisma/client'; +import { Type } from 'class-transformer'; import { IsArray, IsBoolean, IsEnum, IsOptional, IsString, - IsUrl + IsUrl, + ValidateNested } from 'class-validator'; +import { CountryDto } from './country.dto'; + export class CreateAssetProfileDto { @IsEnum(AssetClass) @IsOptional() @@ -25,6 +29,8 @@ export class CreateAssetProfileDto { @IsArray() @IsOptional() + @Type(() => CountryDto) + @ValidateNested({ each: true }) countries?: Prisma.InputJsonArray; @IsCurrencyCode() diff --git a/libs/common/src/lib/dtos/index.ts b/libs/common/src/lib/dtos/index.ts index cf0ce6f57..dea092398 100644 --- a/libs/common/src/lib/dtos/index.ts +++ b/libs/common/src/lib/dtos/index.ts @@ -1,4 +1,5 @@ import { AuthDeviceDto } from './auth-device.dto'; +import { CountryDto } from './country.dto'; import { CreateAccessDto } from './create-access.dto'; import { CreateAccountBalanceDto } from './create-account-balance.dto'; import { CreateAccountWithBalancesDto } from './create-account-with-balances.dto'; @@ -26,6 +27,7 @@ import { UpdateUserSettingDto } from './update-user-setting.dto'; export { AuthDeviceDto, + CountryDto, CreateAccessDto, CreateAccountBalanceDto, CreateAccountDto, diff --git a/libs/common/src/lib/dtos/update-asset-profile.dto.ts b/libs/common/src/lib/dtos/update-asset-profile.dto.ts index 7096023b3..dc660a481 100644 --- a/libs/common/src/lib/dtos/update-asset-profile.dto.ts +++ b/libs/common/src/lib/dtos/update-asset-profile.dto.ts @@ -7,6 +7,7 @@ import { DataSource, Prisma } from '@prisma/client'; +import { Type } from 'class-transformer'; import { IsArray, IsBoolean, @@ -14,9 +15,12 @@ import { IsObject, IsOptional, IsString, - IsUrl + IsUrl, + ValidateNested } from 'class-validator'; +import { CountryDto } from './country.dto'; + export class UpdateAssetProfileDto { @IsEnum(AssetClass) @IsOptional() @@ -32,6 +36,8 @@ export class UpdateAssetProfileDto { @IsArray() @IsOptional() + @Type(() => CountryDto) + @ValidateNested({ each: true }) countries?: Prisma.InputJsonArray; @IsCurrencyCode()