From a08f424cc5564033c0393a74ed6bbf5d2130ece7 Mon Sep 17 00:00:00 2001 From: znn Date: Mon, 22 Jun 2026 17:06:46 +0530 Subject: [PATCH] suport non aws providers 1 (#21927) Title: Relax @IsAWSRegion validation constraint for custom S3-compatible storage endpoints Summary: This PR updates the @IsAWSRegion decorator to support non-standard region slugs (e.g., fr-par) when a custom S3-compatible storage provider is used. Previously, the decorator enforced a strict regex (/^[a-z]{2}-[a-z]+-\d{1}$/) for all region variables, which caused runtime validation errors and worker crashes when users tried to configure non-AWS providers like Scaleway or DigitalOcean that use different region formats. This change introduces a conditional check: If the property being validated is STORAGE_S3_REGION and a STORAGE_S3_ENDPOINT is defined on the configuration object, the strict regex constraint is bypassed, and any non-empty string is accepted. Changes Made is-aws-region.decorator.ts: Updated the IsAWSRegionConstraint class to accept args: ValidationArguments. Added logic to bypass the regex validation if args.property === 'STORAGE_S3_REGION' and object.STORAGE_S3_ENDPOINT is present. TypeScript Typings: **The AwsRegion interface intentionally remains strictly typed as `${string}-${string}-${number}`. This preserves strict compile-time types for standard usage, while class-validator and class-transformer gracefully handle the runtime relaxation during environment variable loading.** Testing I have added below script to test this function ``` const { validate, ValidateIf } = require('class-validator'); const { IsAWSRegion } = require('./packages/twenty-server/dist/engine/core-modules/twenty-config/decorators/is-aws-region.decorator'); class TestConfig { constructor(region, endpoint) { this.STORAGE_S3_REGION = region; this.STORAGE_S3_ENDPOINT = endpoint; } } ValidateIf((env) => !env.STORAGE_S3_ENDPOINT)(TestConfig.prototype, 'STORAGE_S3_REGION'); IsAWSRegion()(TestConfig.prototype, 'STORAGE_S3_REGION'); const config = new TestConfig('fr-par', 'https://s3.fr-par.scw.cloud'); validate(config).then(errors => { if (errors.length > 0) { console.error('Validation failed:'); errors.forEach(err => { console.error(`Property: ${err.property}`); console.error(`Constraints:`, err.constraints); }); } else { console.log('Validation passed!'); } }); ``` Screenshots before Screenshot_2026-06-22_12-51-51 after Screenshot_2026-06-22_12-52-28 Closes https://github.com/twentyhq/twenty/issues/21908 Review in cubic --------- Co-authored-by: Charles Bochet --- .../engine/core-modules/twenty-config/config-variables.ts | 8 ++++++-- .../twenty-config/decorators/is-aws-region.decorator.ts | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/twenty-server/src/engine/core-modules/twenty-config/config-variables.ts b/packages/twenty-server/src/engine/core-modules/twenty-config/config-variables.ts index 3d09464d8e..dfe1b200bd 100644 --- a/packages/twenty-server/src/engine/core-modules/twenty-config/config-variables.ts +++ b/packages/twenty-server/src/engine/core-modules/twenty-config/config-variables.ts @@ -3,7 +3,9 @@ import { Logger } from '@nestjs/common'; import { plainToClass } from 'class-transformer'; import { IsDefined, + IsNotEmpty, IsOptional, + IsString, IsUrl, ValidateIf, type ValidationError, @@ -469,11 +471,13 @@ export class ConfigVariables { @ConfigVariablesMetadata({ group: ConfigVariablesGroup.STORAGE_CONFIG, - description: 'AWS region of the S3 bucket (e.g. eu-west-3). Required.', + description: + 'Region of the S3 bucket (e.g. "eu-west-3" for AWS, or a provider-specific slug like "fr-par" for Scaleway). Required.', type: ConfigVariableType.STRING, }) @ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S_3) - @IsAWSRegion() + @IsString() + @IsNotEmpty() STORAGE_S3_REGION: AwsRegion; @ConfigVariablesMetadata({ diff --git a/packages/twenty-server/src/engine/core-modules/twenty-config/decorators/is-aws-region.decorator.ts b/packages/twenty-server/src/engine/core-modules/twenty-config/decorators/is-aws-region.decorator.ts index 1bef24d917..965a321109 100644 --- a/packages/twenty-server/src/engine/core-modules/twenty-config/decorators/is-aws-region.decorator.ts +++ b/packages/twenty-server/src/engine/core-modules/twenty-config/decorators/is-aws-region.decorator.ts @@ -5,7 +5,7 @@ import { type ValidatorConstraintInterface, } from 'class-validator'; -@ValidatorConstraint({ async: true }) +@ValidatorConstraint({ async: false }) export class IsAWSRegionConstraint implements ValidatorConstraintInterface { validate(region: string) { const regex = /^[a-z]{2}-[a-z]+-\d{1}$/;