mirror of
				https://github.com/lingble/twenty.git
				synced 2025-10-30 20:27:55 +00:00 
			
		
		
		
	Cleanup default values and leftover methods in environmentService (#4550)
* Cleanup default values and leftover methods in environmentService * Adress remainings configService calls
This commit is contained in:
		| @@ -2,16 +2,16 @@ import { ConfigService } from '@nestjs/config'; | ||||
|  | ||||
| import console from 'console'; | ||||
|  | ||||
| import { config } from 'dotenv'; | ||||
| import { DataSource } from 'typeorm'; | ||||
|  | ||||
| config(); | ||||
| const configService = new ConfigService(); | ||||
| import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; | ||||
|  | ||||
| const environmentService = new EnvironmentService(new ConfigService()); | ||||
|  | ||||
| export const connectionSource = new DataSource({ | ||||
|   type: 'postgres', | ||||
|   logging: false, | ||||
|   url: configService.get<string>('PG_DATABASE_URL'), | ||||
|   url: environmentService.get('PG_DATABASE_URL'), | ||||
| }); | ||||
|  | ||||
| export const camelToSnakeCase = (str) => | ||||
|   | ||||
| @@ -1,8 +1,11 @@ | ||||
| import { ConfigService } from '@nestjs/config'; | ||||
|  | ||||
| import { CommandFactory } from 'nest-commander'; | ||||
|  | ||||
| import { filterException } from 'src/engine/filters/utils/global-exception-handler.util'; | ||||
| import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; | ||||
| import { LoggerService } from 'src/engine/integrations/logger/logger.service'; | ||||
| import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; | ||||
|  | ||||
| import { CommandModule } from './command.module'; | ||||
|  | ||||
| @@ -17,8 +20,10 @@ async function bootstrap() { | ||||
|     exceptionHandlerService.captureExceptions([err]); | ||||
|   }; | ||||
|  | ||||
|   const environmentService = new EnvironmentService(new ConfigService()); | ||||
|  | ||||
|   const app = await CommandFactory.createWithoutRunning(CommandModule, { | ||||
|     bufferLogs: process.env.LOGGER_IS_BUFFER_ENABLED === 'true', | ||||
|     bufferLogs: environmentService.get('LOGGER_IS_BUFFER_ENABLED'), | ||||
|     errorHandler, | ||||
|     serviceErrorHandler: errorHandler, | ||||
|   }); | ||||
|   | ||||
| @@ -7,7 +7,7 @@ config(); | ||||
| const configService = new ConfigService(); | ||||
|  | ||||
| export const typeORMCoreModuleOptions: TypeOrmModuleOptions = { | ||||
|   url: configService.get<string>('PG_DATABASE_URL'), | ||||
|   url: configService.get('PG_DATABASE_URL'), | ||||
|   type: 'postgres', | ||||
|   logging: ['error'], | ||||
|   schema: 'core', | ||||
|   | ||||
| @@ -7,7 +7,7 @@ config(); | ||||
| const configService = new ConfigService(); | ||||
|  | ||||
| export const typeORMMetadataModuleOptions: TypeOrmModuleOptions = { | ||||
|   url: configService.get<string>('PG_DATABASE_URL'), | ||||
|   url: configService.get('PG_DATABASE_URL'), | ||||
|   type: 'postgres', | ||||
|   logging: ['error'], | ||||
|   schema: 'metadata', | ||||
|   | ||||
| @@ -8,6 +8,7 @@ import { ApiRestQueryBuilderFactory } from 'src/engine/api/rest/api-rest-query-b | ||||
| import { TokenService } from 'src/engine/modules/auth/services/token.service'; | ||||
| import { ApiRestResponse } from 'src/engine/api/rest/types/api-rest-response.type'; | ||||
| import { ApiRestQuery } from 'src/engine/api/rest/types/api-rest-query.type'; | ||||
| import { getServerUrl } from 'src/utils/get-server-url'; | ||||
|  | ||||
| @Injectable() | ||||
| export class ApiRestService { | ||||
| @@ -22,7 +23,10 @@ export class ApiRestService { | ||||
|     request: Request, | ||||
|     data: ApiRestQuery, | ||||
|   ): Promise<ApiRestResponse> { | ||||
|     const baseUrl = this.environmentService.getBaseUrl(request); | ||||
|     const baseUrl = getServerUrl( | ||||
|       request, | ||||
|       this.environmentService.get('SERVER_URL'), | ||||
|     ); | ||||
|  | ||||
|     try { | ||||
|       return await this.httpService.axiosRef.post(`${baseUrl}/graphql`, data, { | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import { ApiRestQuery } from 'src/engine/api/rest/types/api-rest-query.type'; | ||||
| import { TokenService } from 'src/engine/modules/auth/services/token.service'; | ||||
| import { parseMetadataPath } from 'src/engine/api/rest/api-rest-query-builder/utils/parse-path.utils'; | ||||
| import { capitalize } from 'src/utils/capitalize'; | ||||
| import { getServerUrl } from 'src/utils/get-server-url'; | ||||
|  | ||||
| @Injectable() | ||||
| export class ApiRestMetadataService { | ||||
| @@ -18,7 +19,10 @@ export class ApiRestMetadataService { | ||||
|   ) {} | ||||
|  | ||||
|   async callMetadata(request, data: ApiRestQuery) { | ||||
|     const baseUrl = this.environmentService.getBaseUrl(request); | ||||
|     const baseUrl = getServerUrl( | ||||
|       request, | ||||
|       this.environmentService.get('SERVER_URL'), | ||||
|     ); | ||||
|  | ||||
|     try { | ||||
|       return await this.httpService.axiosRef.post(`${baseUrl}/metadata`, data, { | ||||
|   | ||||
| @@ -21,6 +21,7 @@ import { ExceptionHandlerDriver } from 'src/engine/integrations/exception-handle | ||||
| import { StorageDriverType } from 'src/engine/integrations/file-storage/interfaces'; | ||||
| import { LoggerDriverType } from 'src/engine/integrations/logger/interfaces'; | ||||
| import { IsStrictlyLowerThan } from 'src/engine/integrations/environment/decorators/is-strictly-lower-than.decorator'; | ||||
| import { MessageQueueDriverType } from 'src/engine/integrations/message-queue/interfaces'; | ||||
|  | ||||
| import { IsDuration } from './decorators/is-duration.decorator'; | ||||
| import { AwsRegion } from './interfaces/aws-region.interface'; | ||||
| @@ -35,17 +36,17 @@ export class EnvironmentVariables { | ||||
|   @CastToBoolean() | ||||
|   @IsOptional() | ||||
|   @IsBoolean() | ||||
|   DEBUG_MODE: boolean; | ||||
|   DEBUG_MODE: boolean = false; | ||||
|  | ||||
|   @CastToBoolean() | ||||
|   @IsOptional() | ||||
|   @IsBoolean() | ||||
|   SIGN_IN_PREFILLED: boolean; | ||||
|   SIGN_IN_PREFILLED: boolean = false; | ||||
|  | ||||
|   @CastToBoolean() | ||||
|   @IsOptional() | ||||
|   @IsBoolean() | ||||
|   IS_BILLING_ENABLED: boolean; | ||||
|   IS_BILLING_ENABLED: boolean = false; | ||||
|  | ||||
|   @IsString() | ||||
|   @ValidateIf((env) => env.IS_BILLING_ENABLED === true) | ||||
| @@ -59,7 +60,7 @@ export class EnvironmentVariables { | ||||
|   @CastToPositiveNumber() | ||||
|   @IsOptional() | ||||
|   @ValidateIf((env) => env.IS_BILLING_ENABLED === true) | ||||
|   BILLING_FREE_TRIAL_DURATION_IN_DAYS: number; | ||||
|   BILLING_FREE_TRIAL_DURATION_IN_DAYS: number = 7; | ||||
|  | ||||
|   @IsString() | ||||
|   @ValidateIf((env) => env.IS_BILLING_ENABLED === true) | ||||
| @@ -72,17 +73,17 @@ export class EnvironmentVariables { | ||||
|   @CastToBoolean() | ||||
|   @IsOptional() | ||||
|   @IsBoolean() | ||||
|   TELEMETRY_ENABLED: boolean; | ||||
|   TELEMETRY_ENABLED: boolean = true; | ||||
|  | ||||
|   @CastToBoolean() | ||||
|   @IsOptional() | ||||
|   @IsBoolean() | ||||
|   TELEMETRY_ANONYMIZATION_ENABLED: boolean; | ||||
|   TELEMETRY_ANONYMIZATION_ENABLED: boolean = true; | ||||
|  | ||||
|   @CastToPositiveNumber() | ||||
|   @IsNumber() | ||||
|   @IsOptional() | ||||
|   PORT: number; | ||||
|   PORT: number = 3000; | ||||
|  | ||||
|   // Database | ||||
|   @IsDefined() | ||||
| @@ -108,25 +109,25 @@ export class EnvironmentVariables { | ||||
|  | ||||
|   @IsDuration() | ||||
|   @IsOptional() | ||||
|   ACCESS_TOKEN_EXPIRES_IN: string; | ||||
|   ACCESS_TOKEN_EXPIRES_IN: string = '30m'; | ||||
|  | ||||
|   @IsString() | ||||
|   REFRESH_TOKEN_SECRET: string; | ||||
|  | ||||
|   @IsDuration() | ||||
|   @IsOptional() | ||||
|   REFRESH_TOKEN_EXPIRES_IN: string; | ||||
|   REFRESH_TOKEN_EXPIRES_IN: string = '30m'; | ||||
|  | ||||
|   @IsDuration() | ||||
|   @IsOptional() | ||||
|   REFRESH_TOKEN_COOL_DOWN: string; | ||||
|   REFRESH_TOKEN_COOL_DOWN: string = '1m'; | ||||
|  | ||||
|   @IsString() | ||||
|   LOGIN_TOKEN_SECRET: string; | ||||
|   LOGIN_TOKEN_SECRET: string = '30m'; | ||||
|  | ||||
|   @IsDuration() | ||||
|   @IsOptional() | ||||
|   LOGIN_TOKEN_EXPIRES_IN: string; | ||||
|   LOGIN_TOKEN_EXPIRES_IN: string = '15m'; | ||||
|  | ||||
|   // Auth | ||||
|   @IsUrl({ require_tld: false }) | ||||
| @@ -136,7 +137,7 @@ export class EnvironmentVariables { | ||||
|   @CastToBoolean() | ||||
|   @IsOptional() | ||||
|   @IsBoolean() | ||||
|   AUTH_GOOGLE_ENABLED: boolean; | ||||
|   AUTH_GOOGLE_ENABLED: boolean = false; | ||||
|  | ||||
|   @IsString() | ||||
|   @ValidateIf((env) => env.AUTH_GOOGLE_ENABLED === true) | ||||
| @@ -153,7 +154,7 @@ export class EnvironmentVariables { | ||||
|   // Storage | ||||
|   @IsEnum(StorageDriverType) | ||||
|   @IsOptional() | ||||
|   STORAGE_TYPE: StorageDriverType; | ||||
|   STORAGE_TYPE: StorageDriverType = StorageDriverType.Local; | ||||
|  | ||||
|   @ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3) | ||||
|   @IsAWSRegion() | ||||
| @@ -170,12 +171,12 @@ export class EnvironmentVariables { | ||||
|  | ||||
|   @IsString() | ||||
|   @ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.Local) | ||||
|   STORAGE_LOCAL_PATH: string; | ||||
|   STORAGE_LOCAL_PATH: string = '.local-storage'; | ||||
|  | ||||
|   // Support | ||||
|   @IsEnum(SupportDriver) | ||||
|   @IsOptional() | ||||
|   SUPPORT_DRIVER: SupportDriver; | ||||
|   SUPPORT_DRIVER: SupportDriver = SupportDriver.None; | ||||
|  | ||||
|   @ValidateIf((env) => env.SUPPORT_DRIVER === SupportDriver.Front) | ||||
|   @IsString() | ||||
| @@ -187,19 +188,20 @@ export class EnvironmentVariables { | ||||
|  | ||||
|   @IsEnum(LoggerDriverType) | ||||
|   @IsOptional() | ||||
|   LOGGER_DRIVER: LoggerDriverType; | ||||
|   LOGGER_DRIVER: LoggerDriverType = LoggerDriverType.Console; | ||||
|  | ||||
|   @IsEnum(ExceptionHandlerDriver) | ||||
|   @IsOptional() | ||||
|   EXCEPTION_HANDLER_DRIVER: ExceptionHandlerDriver; | ||||
|   EXCEPTION_HANDLER_DRIVER: ExceptionHandlerDriver = | ||||
|     ExceptionHandlerDriver.Console; | ||||
|  | ||||
|   @CastToLogLevelArray() | ||||
|   @IsOptional() | ||||
|   LOG_LEVELS: LogLevel[]; | ||||
|   LOG_LEVELS: LogLevel[] = ['log', 'error', 'warn']; | ||||
|  | ||||
|   @CastToStringArray() | ||||
|   @IsOptional() | ||||
|   DEMO_WORKSPACE_IDS: string[]; | ||||
|   DEMO_WORKSPACE_IDS: string[] = []; | ||||
|  | ||||
|   @ValidateIf( | ||||
|     (env) => env.EXCEPTION_HANDLER_DRIVER === ExceptionHandlerDriver.Sentry, | ||||
| @@ -209,7 +211,7 @@ export class EnvironmentVariables { | ||||
|  | ||||
|   @IsDuration() | ||||
|   @IsOptional() | ||||
|   PASSWORD_RESET_TOKEN_EXPIRES_IN: string; | ||||
|   PASSWORD_RESET_TOKEN_EXPIRES_IN: string = '5m'; | ||||
|  | ||||
|   @CastToPositiveNumber() | ||||
|   @IsNumber() | ||||
| @@ -219,48 +221,48 @@ export class EnvironmentVariables { | ||||
|       '"WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION" should be strictly lower that "WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION"', | ||||
|   }) | ||||
|   @ValidateIf((env) => env.WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION > 0) | ||||
|   WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION: number; | ||||
|   WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION: number = 30; | ||||
|  | ||||
|   @CastToPositiveNumber() | ||||
|   @IsNumber() | ||||
|   @ValidateIf((env) => env.WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION > 0) | ||||
|   WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION: number; | ||||
|   WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION: number = 60; | ||||
|  | ||||
|   @CastToBoolean() | ||||
|   @IsOptional() | ||||
|   @IsBoolean() | ||||
|   IS_SIGN_UP_DISABLED: boolean; | ||||
|   IS_SIGN_UP_DISABLED: boolean = false; | ||||
|  | ||||
|   @CastToPositiveNumber() | ||||
|   @IsOptional() | ||||
|   @IsNumber() | ||||
|   MUTATION_MAXIMUM_RECORD_AFFECTED: number; | ||||
|   MUTATION_MAXIMUM_RECORD_AFFECTED: number = 100; | ||||
|  | ||||
|   REDIS_HOST: string; | ||||
|   REDIS_HOST: string = '127.0.0.1'; | ||||
|  | ||||
|   REDIS_PORT: number; | ||||
|   REDIS_PORT: number = 6379; | ||||
|  | ||||
|   API_TOKEN_EXPIRES_IN: string; | ||||
|   API_TOKEN_EXPIRES_IN: string = '100y'; | ||||
|  | ||||
|   SHORT_TERM_TOKEN_EXPIRES_IN: string; | ||||
|   SHORT_TERM_TOKEN_EXPIRES_IN: string = '5m'; | ||||
|  | ||||
|   MESSAGING_PROVIDER_GMAIL_ENABLED: boolean; | ||||
|   MESSAGING_PROVIDER_GMAIL_ENABLED: boolean = false; | ||||
|  | ||||
|   MESSAGING_PROVIDER_GMAIL_CALLBACK_URL: string; | ||||
|  | ||||
|   MESSAGE_QUEUE_TYPE: string; | ||||
|   MESSAGE_QUEUE_TYPE: string = MessageQueueDriverType.Sync; | ||||
|  | ||||
|   EMAIL_FROM_ADDRESS: string; | ||||
|   EMAIL_FROM_ADDRESS: string = 'noreply@yourdomain.com'; | ||||
|  | ||||
|   EMAIL_SYSTEM_ADDRESS: string; | ||||
|   EMAIL_SYSTEM_ADDRESS: string = 'system@yourdomain.com'; | ||||
|  | ||||
|   EMAIL_FROM_NAME: string; | ||||
|   EMAIL_FROM_NAME: string = 'Felix from Twenty'; | ||||
|  | ||||
|   EMAIL_DRIVER: EmailDriver; | ||||
|   EMAIL_DRIVER: EmailDriver = EmailDriver.Logger; | ||||
|  | ||||
|   EMAIL_SMTP_HOST: string; | ||||
|  | ||||
|   EMAIL_SMTP_PORT: number; | ||||
|   EMAIL_SMTP_PORT: number = 587; | ||||
|  | ||||
|   EMAIL_SMTP_USER: string; | ||||
|  | ||||
| @@ -268,15 +270,19 @@ export class EnvironmentVariables { | ||||
|  | ||||
|   OPENROUTER_API_KEY: string; | ||||
|  | ||||
|   API_RATE_LIMITING_TTL: number; | ||||
|   API_RATE_LIMITING_TTL: number = 100; | ||||
|  | ||||
|   API_RATE_LIMITING_LIMIT: number; | ||||
|   API_RATE_LIMITING_LIMIT: number = 500; | ||||
|  | ||||
|   CACHE_STORAGE_TYPE: string; | ||||
|   CACHE_STORAGE_TYPE: string = 'memory'; | ||||
|  | ||||
|   CACHE_STORAGE_TTL: number = 3600 * 24 * 7; | ||||
|  | ||||
|   CALENDAR_PROVIDER_GOOGLE_ENABLED: boolean = false; | ||||
|  | ||||
|   CACHE_STORAGE_TTL: number; | ||||
|   CALENDAR_PROVIDER_GOOGLE_ENABLED: boolean; | ||||
|   AUTH_GOOGLE_APIS_CALLBACK_URL: string; | ||||
|  | ||||
|   LOGGER_IS_BUFFER_ENABLED: boolean = true; | ||||
| } | ||||
|  | ||||
| export const validate = (config: Record<string, unknown>) => { | ||||
|   | ||||
| @@ -1,77 +0,0 @@ | ||||
| import { EmailDriver } from 'src/engine/integrations/email/interfaces/email.interface'; | ||||
| import { SupportDriver } from 'src/engine/integrations/environment/interfaces/support.interface'; | ||||
|  | ||||
| import { ExceptionHandlerDriver } from 'src/engine/integrations/exception-handler/interfaces'; | ||||
| import { StorageDriverType } from 'src/engine/integrations/file-storage/interfaces'; | ||||
| import { LoggerDriverType } from 'src/engine/integrations/logger/interfaces'; | ||||
| import { MessageQueueDriverType } from 'src/engine/integrations/message-queue/interfaces'; | ||||
| import { EnvironmentVariables } from 'src/engine/integrations/environment/environment-variables'; | ||||
|  | ||||
| const EnvironmentDefault = new EnvironmentVariables(); | ||||
|  | ||||
| EnvironmentDefault.DEBUG_MODE = false; | ||||
| EnvironmentDefault.SIGN_IN_PREFILLED = false; | ||||
| EnvironmentDefault.IS_BILLING_ENABLED = false; | ||||
| EnvironmentDefault.BILLING_PLAN_REQUIRED_LINK = ''; | ||||
| EnvironmentDefault.BILLING_STRIPE_BASE_PLAN_PRODUCT_ID = ''; | ||||
| EnvironmentDefault.BILLING_FREE_TRIAL_DURATION_IN_DAYS = 7; | ||||
| EnvironmentDefault.BILLING_STRIPE_API_KEY = ''; | ||||
| EnvironmentDefault.BILLING_STRIPE_WEBHOOK_SECRET = ''; | ||||
| EnvironmentDefault.TELEMETRY_ENABLED = true; | ||||
| EnvironmentDefault.TELEMETRY_ANONYMIZATION_ENABLED = true; | ||||
| EnvironmentDefault.PORT = 3000; | ||||
| EnvironmentDefault.REDIS_HOST = '127.0.0.1'; | ||||
| EnvironmentDefault.REDIS_PORT = 6379; | ||||
| EnvironmentDefault.PG_DATABASE_URL = ''; | ||||
| EnvironmentDefault.FRONT_BASE_URL = ''; | ||||
| EnvironmentDefault.SERVER_URL = ''; | ||||
| EnvironmentDefault.ACCESS_TOKEN_SECRET = 'random_string'; | ||||
| EnvironmentDefault.ACCESS_TOKEN_EXPIRES_IN = '30m'; | ||||
| EnvironmentDefault.REFRESH_TOKEN_SECRET = 'random_string'; | ||||
| EnvironmentDefault.REFRESH_TOKEN_EXPIRES_IN = '30m'; | ||||
| EnvironmentDefault.REFRESH_TOKEN_COOL_DOWN = '1m'; | ||||
| EnvironmentDefault.LOGIN_TOKEN_SECRET = 'random_string'; | ||||
| EnvironmentDefault.LOGIN_TOKEN_EXPIRES_IN = '30m'; | ||||
| EnvironmentDefault.API_TOKEN_EXPIRES_IN = '100y'; | ||||
| EnvironmentDefault.SHORT_TERM_TOKEN_EXPIRES_IN = '5m'; | ||||
| EnvironmentDefault.FRONT_AUTH_CALLBACK_URL = ''; | ||||
| EnvironmentDefault.MESSAGING_PROVIDER_GMAIL_ENABLED = false; | ||||
| EnvironmentDefault.MESSAGING_PROVIDER_GMAIL_CALLBACK_URL = ''; | ||||
| EnvironmentDefault.AUTH_GOOGLE_ENABLED = false; | ||||
| EnvironmentDefault.AUTH_GOOGLE_CLIENT_ID = ''; | ||||
| EnvironmentDefault.AUTH_GOOGLE_CLIENT_SECRET = ''; | ||||
| EnvironmentDefault.AUTH_GOOGLE_CALLBACK_URL = ''; | ||||
| EnvironmentDefault.STORAGE_TYPE = StorageDriverType.Local; | ||||
| EnvironmentDefault.STORAGE_S3_REGION = 'aws-east-1'; | ||||
| EnvironmentDefault.STORAGE_S3_NAME = ''; | ||||
| EnvironmentDefault.STORAGE_S3_ENDPOINT = ''; | ||||
| EnvironmentDefault.STORAGE_LOCAL_PATH = '.local-storage'; | ||||
| EnvironmentDefault.MESSAGE_QUEUE_TYPE = MessageQueueDriverType.Sync; | ||||
| EnvironmentDefault.EMAIL_FROM_ADDRESS = 'noreply@yourdomain.com'; | ||||
| EnvironmentDefault.EMAIL_SYSTEM_ADDRESS = 'system@yourdomain.com'; | ||||
| EnvironmentDefault.EMAIL_FROM_NAME = 'John from Twenty'; | ||||
| EnvironmentDefault.EMAIL_DRIVER = EmailDriver.Logger; | ||||
| EnvironmentDefault.EMAIL_SMTP_HOST = ''; | ||||
| EnvironmentDefault.EMAIL_SMTP_PORT = 587; | ||||
| EnvironmentDefault.EMAIL_SMTP_USER = ''; | ||||
| EnvironmentDefault.EMAIL_SMTP_PASSWORD = ''; | ||||
| EnvironmentDefault.SUPPORT_DRIVER = SupportDriver.None; | ||||
| EnvironmentDefault.SUPPORT_FRONT_CHAT_ID = ''; | ||||
| EnvironmentDefault.SUPPORT_FRONT_HMAC_KEY = ''; | ||||
| EnvironmentDefault.LOGGER_DRIVER = LoggerDriverType.Console; | ||||
| EnvironmentDefault.EXCEPTION_HANDLER_DRIVER = ExceptionHandlerDriver.Console; | ||||
| EnvironmentDefault.LOG_LEVELS = ['log', 'error', 'warn']; | ||||
| EnvironmentDefault.SENTRY_DSN = ''; | ||||
| EnvironmentDefault.DEMO_WORKSPACE_IDS = []; | ||||
| EnvironmentDefault.OPENROUTER_API_KEY = ''; | ||||
| EnvironmentDefault.PASSWORD_RESET_TOKEN_EXPIRES_IN = '5m'; | ||||
| EnvironmentDefault.WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION = 30; | ||||
| EnvironmentDefault.WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION = 60; | ||||
| EnvironmentDefault.IS_SIGN_UP_DISABLED = false; | ||||
| EnvironmentDefault.API_RATE_LIMITING_TTL = 100; | ||||
| EnvironmentDefault.API_RATE_LIMITING_LIMIT = 500; | ||||
| EnvironmentDefault.MUTATION_MAXIMUM_RECORD_AFFECTED = 100; | ||||
| EnvironmentDefault.CACHE_STORAGE_TYPE = 'memory'; | ||||
| EnvironmentDefault.CACHE_STORAGE_TTL = 3600 * 24 * 7; | ||||
|  | ||||
| export { EnvironmentDefault }; | ||||
| @@ -2,47 +2,16 @@ | ||||
| import { Injectable } from '@nestjs/common'; | ||||
| import { ConfigService } from '@nestjs/config'; | ||||
|  | ||||
| import { Request } from 'express'; | ||||
|  | ||||
| import { EnvironmentVariables } from 'src/engine/integrations/environment/environment-variables'; | ||||
| import { EnvironmentDefault } from 'src/engine/integrations/environment/environment.default'; | ||||
|  | ||||
| @Injectable() | ||||
| export class EnvironmentService { | ||||
|   constructor(private configService: ConfigService) {} | ||||
|   constructor(private readonly configService: ConfigService) {} | ||||
|  | ||||
|   get<T extends keyof EnvironmentVariables>(key: T): EnvironmentVariables[T] { | ||||
|     return ( | ||||
|       this.configService.get<EnvironmentVariables[T]>(key) ?? | ||||
|       EnvironmentDefault[key] | ||||
|     return this.configService.get<EnvironmentVariables[T]>( | ||||
|       key, | ||||
|       new EnvironmentVariables()[key], | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   getServerUrl(): string { | ||||
|     const url = this.configService.get<string>('SERVER_URL')!; | ||||
|  | ||||
|     if (url?.endsWith('/')) { | ||||
|       return url.substring(0, url.length - 1); | ||||
|     } | ||||
|  | ||||
|     return url; | ||||
|   } | ||||
|  | ||||
|   getBaseUrl(request: Request): string { | ||||
|     return ( | ||||
|       this.getServerUrl() || `${request.protocol}://${request.get('host')}` | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   getFrontAuthCallbackUrl(): string { | ||||
|     return ( | ||||
|       this.configService.get<string>('FRONT_AUTH_CALLBACK_URL') ?? | ||||
|       this.get('FRONT_BASE_URL') + '/verify' | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   // TODO: check because it isn't called | ||||
|   getLoggerIsBufferEnabled(): boolean | undefined { | ||||
|     return this.configService.get<boolean>('LOGGER_IS_BUFFER_ENABLED') ?? true; | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -361,7 +361,9 @@ export class TokenService { | ||||
|   } | ||||
|  | ||||
|   computeRedirectURI(loginToken: string): string { | ||||
|     return `${this.environmentService.getFrontAuthCallbackUrl()}?loginToken=${loginToken}`; | ||||
|     return `${this.environmentService.get( | ||||
|       'FRONT_BASE_URL', | ||||
|     )}/verify?loginToken=${loginToken}`; | ||||
|   } | ||||
|  | ||||
|   async verifyJwt(token: string, secret?: string) { | ||||
|   | ||||
| @@ -26,11 +26,11 @@ class Billing { | ||||
|   @Field(() => Boolean) | ||||
|   isBillingEnabled: boolean; | ||||
|  | ||||
|   @Field(() => String) | ||||
|   billingUrl: string; | ||||
|   @Field(() => String, { nullable: true }) | ||||
|   billingUrl?: string; | ||||
|  | ||||
|   @Field(() => Number, { nullable: true }) | ||||
|   billingFreeTrialDurationInDays: number | undefined; | ||||
|   billingFreeTrialDurationInDays?: number; | ||||
| } | ||||
|  | ||||
| @ObjectType() | ||||
| @@ -39,13 +39,13 @@ class Support { | ||||
|   supportDriver: string; | ||||
|  | ||||
|   @Field(() => String, { nullable: true }) | ||||
|   supportFrontChatId: string | undefined; | ||||
|   supportFrontChatId?: string; | ||||
| } | ||||
|  | ||||
| @ObjectType() | ||||
| class Sentry { | ||||
|   @Field(() => String, { nullable: true }) | ||||
|   dsn: string | undefined; | ||||
|   dsn?: string; | ||||
| } | ||||
|  | ||||
| @ObjectType() | ||||
|   | ||||
| @@ -26,6 +26,7 @@ import { | ||||
| } from 'src/engine/modules/open-api/utils/responses.utils'; | ||||
| import { getRequestBody } from 'src/engine/modules/open-api/utils/request-body.utils'; | ||||
| import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; | ||||
| import { getServerUrl } from 'src/utils/get-server-url'; | ||||
|  | ||||
| @Injectable() | ||||
| export class OpenApiService { | ||||
| @@ -36,7 +37,10 @@ export class OpenApiService { | ||||
|   ) {} | ||||
|  | ||||
|   async generateCoreSchema(request: Request): Promise<OpenAPIV3_1.Document> { | ||||
|     const baseUrl = this.environmentService.getBaseUrl(request); | ||||
|     const baseUrl = getServerUrl( | ||||
|       request, | ||||
|       this.environmentService.get('SERVER_URL'), | ||||
|     ); | ||||
|  | ||||
|     const schema = baseSchema('core', baseUrl); | ||||
|  | ||||
| @@ -93,7 +97,10 @@ export class OpenApiService { | ||||
|   async generateMetaDataSchema( | ||||
|     request: Request, | ||||
|   ): Promise<OpenAPIV3_1.Document> { | ||||
|     const baseUrl = this.environmentService.getBaseUrl(request); | ||||
|     const baseUrl = getServerUrl( | ||||
|       request, | ||||
|       this.environmentService.get('SERVER_URL'), | ||||
|     ); | ||||
|  | ||||
|     const schema = baseSchema('metadata', baseUrl); | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { NestFactory } from '@nestjs/core'; | ||||
| import { ValidationPipe } from '@nestjs/common'; | ||||
| import { NestExpressApplication } from '@nestjs/platform-express'; | ||||
| import { ConfigService } from '@nestjs/config'; | ||||
|  | ||||
| import * as Sentry from '@sentry/node'; | ||||
| import { graphqlUploadExpress } from 'graphql-upload'; | ||||
| @@ -15,9 +16,11 @@ import { LoggerService } from './engine/integrations/logger/logger.service'; | ||||
| import { EnvironmentService } from './engine/integrations/environment/environment.service'; | ||||
|  | ||||
| const bootstrap = async () => { | ||||
|   const environmentService = new EnvironmentService(new ConfigService()); | ||||
|  | ||||
|   const app = await NestFactory.create<NestExpressApplication>(AppModule, { | ||||
|     cors: true, | ||||
|     bufferLogs: process.env.LOGGER_IS_BUFFER_ENABLED === 'true', | ||||
|     bufferLogs: environmentService.get('LOGGER_IS_BUFFER_ENABLED'), | ||||
|     rawBody: true, | ||||
|   }); | ||||
|   const logger = app.get(LoggerService); | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import { NestFactory } from '@nestjs/core'; | ||||
| import { ConfigService } from '@nestjs/config'; | ||||
|  | ||||
| import { | ||||
|   MessageQueueJob, | ||||
| @@ -13,14 +14,17 @@ import { MessageQueue } from 'src/engine/integrations/message-queue/message-queu | ||||
| import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; | ||||
| import { getJobClassName } from 'src/engine/integrations/message-queue/utils/get-job-class-name.util'; | ||||
| import { QueueWorkerModule } from 'src/queue-worker/queue-worker.module'; | ||||
| import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; | ||||
|  | ||||
| async function bootstrap() { | ||||
|   let exceptionHandlerService: ExceptionHandlerService | undefined; | ||||
|   let loggerService: LoggerService | undefined; | ||||
|  | ||||
|   try { | ||||
|     const environmentService = new EnvironmentService(new ConfigService()); | ||||
|  | ||||
|     const app = await NestFactory.createApplicationContext(QueueWorkerModule, { | ||||
|       bufferLogs: process.env.LOGGER_IS_BUFFER_ENABLED === 'true', | ||||
|       bufferLogs: environmentService.get('LOGGER_IS_BUFFER_ENABLED'), | ||||
|     }); | ||||
|  | ||||
|     loggerService = app.get(LoggerService); | ||||
|   | ||||
							
								
								
									
										11
									
								
								packages/twenty-server/src/utils/get-server-url.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								packages/twenty-server/src/utils/get-server-url.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| import { Request } from 'express'; | ||||
|  | ||||
| export const getServerUrl = ( | ||||
|   request: Request, | ||||
|   serverUrlEnv: string, | ||||
| ): string => { | ||||
|   if (serverUrlEnv?.endsWith('/')) | ||||
|     return serverUrlEnv.substring(0, serverUrlEnv.length - 1); | ||||
|  | ||||
|   return serverUrlEnv || `${request.protocol}://${request.get('host')}`; | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user
	 Félix Malfait
					Félix Malfait