rename core-module environment to twenty-config (#11445)

closes https://github.com/twentyhq/core-team-issues/issues/759
This commit is contained in:
nitin
2025-04-09 17:41:26 +05:30
committed by GitHub
parent fe6d0241a8
commit bd3ec6d5e3
193 changed files with 1454 additions and 1422 deletions

View File

@ -145,6 +145,25 @@ export type Billing = {
trialPeriods: Array<BillingTrialPeriodDto>;
};
export type BillingEndTrialPeriodOutput = {
__typename?: 'BillingEndTrialPeriodOutput';
/** Boolean that confirms if a payment method was found */
hasPaymentMethod: Scalars['Boolean']['output'];
/** Updated subscription status */
status?: Maybe<SubscriptionStatus>;
};
export type BillingMeteredProductUsageOutput = {
__typename?: 'BillingMeteredProductUsageOutput';
includedFreeQuantity: Scalars['Float']['output'];
periodEnd: Scalars['DateTime']['output'];
periodStart: Scalars['DateTime']['output'];
productKey: BillingProductKey;
totalCostCents: Scalars['Float']['output'];
unitPriceCents: Scalars['Float']['output'];
usageQuantity: Scalars['Float']['output'];
};
/** The different billing plans available */
export enum BillingPlanKey {
ENTERPRISE = 'ENTERPRISE',
@ -153,9 +172,9 @@ export enum BillingPlanKey {
export type BillingPlanOutput = {
__typename?: 'BillingPlanOutput';
baseProduct: BillingProductDto;
meteredProducts: Array<BillingProductDto>;
otherLicensedProducts: Array<BillingProductDto>;
baseProduct: BillingProduct;
meteredProducts: Array<BillingProduct>;
otherLicensedProducts: Array<BillingProduct>;
planKey: BillingPlanKey;
};
@ -191,13 +210,26 @@ export enum BillingPriceTiersMode {
export type BillingPriceUnionDto = BillingPriceLicensedDto | BillingPriceMeteredDto;
export type BillingProductDto = {
__typename?: 'BillingProductDTO';
export type BillingProduct = {
__typename?: 'BillingProduct';
description: Scalars['String']['output'];
images?: Maybe<Array<Scalars['String']['output']>>;
metadata: BillingProductMetadata;
name: Scalars['String']['output'];
prices: Array<BillingPriceUnionDto>;
type: BillingUsageType;
prices?: Maybe<Array<BillingPriceUnionDto>>;
};
/** The different billing products available */
export enum BillingProductKey {
BASE_PRODUCT = 'BASE_PRODUCT',
WORKFLOW_NODE_EXECUTION = 'WORKFLOW_NODE_EXECUTION'
}
export type BillingProductMetadata = {
__typename?: 'BillingProductMetadata';
planKey: BillingPlanKey;
priceUsageBased: BillingUsageType;
productKey: BillingProductKey;
};
export type BillingSessionOutput = {
@ -207,11 +239,19 @@ export type BillingSessionOutput = {
export type BillingSubscription = {
__typename?: 'BillingSubscription';
billingSubscriptionItems?: Maybe<Array<BillingSubscriptionItem>>;
id: Scalars['UUID']['output'];
interval?: Maybe<SubscriptionInterval>;
status: SubscriptionStatus;
};
export type BillingSubscriptionItem = {
__typename?: 'BillingSubscriptionItem';
billingProduct?: Maybe<BillingProduct>;
hasReachedCurrentPeriodCap: Scalars['Boolean']['output'];
id: Scalars['UUID']['output'];
};
export type BillingTrialPeriodDto = {
__typename?: 'BillingTrialPeriodDTO';
duration: Scalars['Float']['output'];
@ -280,6 +320,49 @@ export type ComputeStepOutputSchemaInput = {
step: Scalars['JSON']['input'];
};
export type ConfigVariable = {
__typename?: 'ConfigVariable';
description: Scalars['String']['output'];
isSensitive: Scalars['Boolean']['output'];
name: Scalars['String']['output'];
value: Scalars['String']['output'];
};
export enum ConfigVariablesGroup {
AnalyticsConfig = 'AnalyticsConfig',
BillingConfig = 'BillingConfig',
CaptchaConfig = 'CaptchaConfig',
CloudflareConfig = 'CloudflareConfig',
EmailSettings = 'EmailSettings',
ExceptionHandler = 'ExceptionHandler',
GoogleAuth = 'GoogleAuth',
LLM = 'LLM',
Logging = 'Logging',
Metering = 'Metering',
MicrosoftAuth = 'MicrosoftAuth',
Other = 'Other',
RateLimiting = 'RateLimiting',
SSL = 'SSL',
ServerConfig = 'ServerConfig',
ServerlessConfig = 'ServerlessConfig',
StorageConfig = 'StorageConfig',
SupportChatConfig = 'SupportChatConfig',
TokensDuration = 'TokensDuration'
}
export type ConfigVariablesGroupData = {
__typename?: 'ConfigVariablesGroupData';
description: Scalars['String']['output'];
isHiddenOnLoad: Scalars['Boolean']['output'];
name: ConfigVariablesGroup;
variables: Array<ConfigVariable>;
};
export type ConfigVariablesOutput = {
__typename?: 'ConfigVariablesOutput';
groups: Array<ConfigVariablesGroupData>;
};
export type CreateAppTokenInput = {
expiresAt: Scalars['DateTime']['input'];
};
@ -498,49 +581,6 @@ export type EmailPasswordResetLink = {
success: Scalars['Boolean']['output'];
};
export type EnvironmentVariable = {
__typename?: 'EnvironmentVariable';
description: Scalars['String']['output'];
name: Scalars['String']['output'];
sensitive: Scalars['Boolean']['output'];
value: Scalars['String']['output'];
};
export enum EnvironmentVariablesGroup {
AnalyticsConfig = 'AnalyticsConfig',
BillingConfig = 'BillingConfig',
CaptchaConfig = 'CaptchaConfig',
CloudflareConfig = 'CloudflareConfig',
EmailSettings = 'EmailSettings',
ExceptionHandler = 'ExceptionHandler',
GoogleAuth = 'GoogleAuth',
LLM = 'LLM',
Logging = 'Logging',
Metering = 'Metering',
MicrosoftAuth = 'MicrosoftAuth',
Other = 'Other',
RateLimiting = 'RateLimiting',
SSL = 'SSL',
ServerConfig = 'ServerConfig',
ServerlessConfig = 'ServerlessConfig',
StorageConfig = 'StorageConfig',
SupportChatConfig = 'SupportChatConfig',
TokensDuration = 'TokensDuration'
}
export type EnvironmentVariablesGroupData = {
__typename?: 'EnvironmentVariablesGroupData';
description: Scalars['String']['output'];
isHiddenOnLoad: Scalars['Boolean']['output'];
name: EnvironmentVariablesGroup;
variables: Array<EnvironmentVariable>;
};
export type EnvironmentVariablesOutput = {
__typename?: 'EnvironmentVariablesOutput';
groups: Array<EnvironmentVariablesGroupData>;
};
export type ExecuteServerlessFunctionInput = {
/** Id of the serverless function to execute */
id: Scalars['UUID']['input'];
@ -908,6 +948,7 @@ export type Mutation = {
editSSOIdentityProvider: EditSsoOutput;
emailPasswordResetLink: EmailPasswordResetLink;
enablePostgresProxy: PostgresCredentials;
endSubscriptionTrialPeriod: BillingEndTrialPeriodOutput;
executeOneServerlessFunction: ServerlessFunctionExecutionResult;
generateApiKeyToken: ApiKeyToken;
generateTransientToken: TransientToken;
@ -926,11 +967,11 @@ export type Mutation = {
signUpInNewWorkspace: SignUpOutput;
skipSyncEmailOnboardingStep: OnboardingStepSuccess;
submitFormStep: Scalars['Boolean']['output'];
switchToYearlyInterval: BillingUpdateOutput;
syncRemoteTable: RemoteTable;
syncRemoteTableSchemaChanges: RemoteTable;
track: Analytics;
unsyncRemoteTable: RemoteTable;
updateBillingSubscription: BillingUpdateOutput;
updateLabPublicFeatureFlag: FeatureFlag;
updateOneField: Field;
updateOneObject: Object;
@ -1524,8 +1565,9 @@ export type Query = {
findWorkspaceInvitations: Array<WorkspaceInvitation>;
getApprovedAccessDomains: Array<ApprovedAccessDomain>;
getAvailablePackages: Scalars['JSON']['output'];
getEnvironmentVariablesGrouped: EnvironmentVariablesOutput;
getConfigVariablesGrouped: ConfigVariablesOutput;
getIndicatorHealthStatus: AdminPanelHealthServiceData;
getMeteredProductsUsage: Array<BillingMeteredProductUsageOutput>;
getPostgresCredentials?: Maybe<PostgresCredentials>;
getPublicWorkspaceDataByDomain: PublicWorkspaceDataOutput;
getQueueMetrics: QueueMetricsData;
@ -1545,6 +1587,7 @@ export type Query = {
relationMetadata: RelationMetadataConnection;
search: Array<SearchRecord>;
validatePasswordResetToken: ValidatePasswordResetToken;
versionInfo: VersionInfo;
};
@ -2369,6 +2412,12 @@ export type ValidatePasswordResetToken = {
id: Scalars['String']['output'];
};
export type VersionInfo = {
__typename?: 'VersionInfo';
currentVersion?: Maybe<Scalars['String']['output']>;
latestVersion: Scalars['String']['output'];
};
export type WorkerQueueMetrics = {
__typename?: 'WorkerQueueMetrics';
active: Scalars['Float']['output'];

View File

@ -312,6 +312,49 @@ export type ComputeStepOutputSchemaInput = {
step: Scalars['JSON'];
};
export type ConfigVariable = {
__typename?: 'ConfigVariable';
description: Scalars['String'];
isSensitive: Scalars['Boolean'];
name: Scalars['String'];
value: Scalars['String'];
};
export enum ConfigVariablesGroup {
AnalyticsConfig = 'AnalyticsConfig',
BillingConfig = 'BillingConfig',
CaptchaConfig = 'CaptchaConfig',
CloudflareConfig = 'CloudflareConfig',
EmailSettings = 'EmailSettings',
ExceptionHandler = 'ExceptionHandler',
GoogleAuth = 'GoogleAuth',
LLM = 'LLM',
Logging = 'Logging',
Metering = 'Metering',
MicrosoftAuth = 'MicrosoftAuth',
Other = 'Other',
RateLimiting = 'RateLimiting',
SSL = 'SSL',
ServerConfig = 'ServerConfig',
ServerlessConfig = 'ServerlessConfig',
StorageConfig = 'StorageConfig',
SupportChatConfig = 'SupportChatConfig',
TokensDuration = 'TokensDuration'
}
export type ConfigVariablesGroupData = {
__typename?: 'ConfigVariablesGroupData';
description: Scalars['String'];
isHiddenOnLoad: Scalars['Boolean'];
name: ConfigVariablesGroup;
variables: Array<ConfigVariable>;
};
export type ConfigVariablesOutput = {
__typename?: 'ConfigVariablesOutput';
groups: Array<ConfigVariablesGroupData>;
};
export type CreateApprovedAccessDomainInput = {
domain: Scalars['String'];
email: Scalars['String'];
@ -469,49 +512,6 @@ export type EmailPasswordResetLink = {
success: Scalars['Boolean'];
};
export type EnvironmentVariable = {
__typename?: 'EnvironmentVariable';
description: Scalars['String'];
name: Scalars['String'];
sensitive: Scalars['Boolean'];
value: Scalars['String'];
};
export enum EnvironmentVariablesGroup {
AnalyticsConfig = 'AnalyticsConfig',
BillingConfig = 'BillingConfig',
CaptchaConfig = 'CaptchaConfig',
CloudflareConfig = 'CloudflareConfig',
EmailSettings = 'EmailSettings',
ExceptionHandler = 'ExceptionHandler',
GoogleAuth = 'GoogleAuth',
LLM = 'LLM',
Logging = 'Logging',
Metering = 'Metering',
MicrosoftAuth = 'MicrosoftAuth',
Other = 'Other',
RateLimiting = 'RateLimiting',
SSL = 'SSL',
ServerConfig = 'ServerConfig',
ServerlessConfig = 'ServerlessConfig',
StorageConfig = 'StorageConfig',
SupportChatConfig = 'SupportChatConfig',
TokensDuration = 'TokensDuration'
}
export type EnvironmentVariablesGroupData = {
__typename?: 'EnvironmentVariablesGroupData';
description: Scalars['String'];
isHiddenOnLoad: Scalars['Boolean'];
name: EnvironmentVariablesGroup;
variables: Array<EnvironmentVariable>;
};
export type EnvironmentVariablesOutput = {
__typename?: 'EnvironmentVariablesOutput';
groups: Array<EnvironmentVariablesGroupData>;
};
export type ExecuteServerlessFunctionInput = {
/** Id of the serverless function to execute */
id: Scalars['UUID'];
@ -1428,7 +1428,7 @@ export type Query = {
findWorkspaceInvitations: Array<WorkspaceInvitation>;
getApprovedAccessDomains: Array<ApprovedAccessDomain>;
getAvailablePackages: Scalars['JSON'];
getEnvironmentVariablesGrouped: EnvironmentVariablesOutput;
getConfigVariablesGrouped: ConfigVariablesOutput;
getIndicatorHealthStatus: AdminPanelHealthServiceData;
getMeteredProductsUsage: Array<BillingMeteredProductUsageOutput>;
getPostgresCredentials?: Maybe<PostgresCredentials>;
@ -2625,10 +2625,10 @@ export type UserLookupAdminPanelMutationVariables = Exact<{
export type UserLookupAdminPanelMutation = { __typename?: 'Mutation', userLookupAdminPanel: { __typename?: 'UserLookup', user: { __typename?: 'UserInfo', id: string, email: string, firstName?: string | null, lastName?: string | null }, workspaces: Array<{ __typename?: 'WorkspaceInfo', id: string, name: string, logo?: string | null, totalUsers: number, allowImpersonation: boolean, users: Array<{ __typename?: 'UserInfo', id: string, email: string, firstName?: string | null, lastName?: string | null }>, featureFlags: Array<{ __typename?: 'FeatureFlag', key: FeatureFlagKey, value: boolean }> }> } };
export type GetEnvironmentVariablesGroupedQueryVariables = Exact<{ [key: string]: never; }>;
export type GetConfigVariablesGroupedQueryVariables = Exact<{ [key: string]: never; }>;
export type GetEnvironmentVariablesGroupedQuery = { __typename?: 'Query', getEnvironmentVariablesGrouped: { __typename?: 'EnvironmentVariablesOutput', groups: Array<{ __typename?: 'EnvironmentVariablesGroupData', name: EnvironmentVariablesGroup, description: string, isHiddenOnLoad: boolean, variables: Array<{ __typename?: 'EnvironmentVariable', name: string, description: string, value: string, sensitive: boolean }> }> } };
export type GetConfigVariablesGroupedQuery = { __typename?: 'Query', getConfigVariablesGrouped: { __typename?: 'ConfigVariablesOutput', groups: Array<{ __typename?: 'ConfigVariablesGroupData', name: ConfigVariablesGroup, description: string, isHiddenOnLoad: boolean, variables: Array<{ __typename?: 'ConfigVariable', name: string, description: string, value: string, isSensitive: boolean }> }> } };
export type GetVersionInfoQueryVariables = Exact<{ [key: string]: never; }>;
@ -4578,9 +4578,9 @@ export function useUserLookupAdminPanelMutation(baseOptions?: Apollo.MutationHoo
export type UserLookupAdminPanelMutationHookResult = ReturnType<typeof useUserLookupAdminPanelMutation>;
export type UserLookupAdminPanelMutationResult = Apollo.MutationResult<UserLookupAdminPanelMutation>;
export type UserLookupAdminPanelMutationOptions = Apollo.BaseMutationOptions<UserLookupAdminPanelMutation, UserLookupAdminPanelMutationVariables>;
export const GetEnvironmentVariablesGroupedDocument = gql`
query GetEnvironmentVariablesGrouped {
getEnvironmentVariablesGrouped {
export const GetConfigVariablesGroupedDocument = gql`
query GetConfigVariablesGrouped {
getConfigVariablesGrouped {
groups {
name
description
@ -4589,7 +4589,7 @@ export const GetEnvironmentVariablesGroupedDocument = gql`
name
description
value
sensitive
isSensitive
}
}
}
@ -4597,31 +4597,31 @@ export const GetEnvironmentVariablesGroupedDocument = gql`
`;
/**
* __useGetEnvironmentVariablesGroupedQuery__
* __useGetConfigVariablesGroupedQuery__
*
* To run a query within a React component, call `useGetEnvironmentVariablesGroupedQuery` and pass it any options that fit your needs.
* When your component renders, `useGetEnvironmentVariablesGroupedQuery` returns an object from Apollo Client that contains loading, error, and data properties
* To run a query within a React component, call `useGetConfigVariablesGroupedQuery` and pass it any options that fit your needs.
* When your component renders, `useGetConfigVariablesGroupedQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useGetEnvironmentVariablesGroupedQuery({
* const { data, loading, error } = useGetConfigVariablesGroupedQuery({
* variables: {
* },
* });
*/
export function useGetEnvironmentVariablesGroupedQuery(baseOptions?: Apollo.QueryHookOptions<GetEnvironmentVariablesGroupedQuery, GetEnvironmentVariablesGroupedQueryVariables>) {
export function useGetConfigVariablesGroupedQuery(baseOptions?: Apollo.QueryHookOptions<GetConfigVariablesGroupedQuery, GetConfigVariablesGroupedQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<GetEnvironmentVariablesGroupedQuery, GetEnvironmentVariablesGroupedQueryVariables>(GetEnvironmentVariablesGroupedDocument, options);
return Apollo.useQuery<GetConfigVariablesGroupedQuery, GetConfigVariablesGroupedQueryVariables>(GetConfigVariablesGroupedDocument, options);
}
export function useGetEnvironmentVariablesGroupedLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetEnvironmentVariablesGroupedQuery, GetEnvironmentVariablesGroupedQueryVariables>) {
export function useGetConfigVariablesGroupedLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetConfigVariablesGroupedQuery, GetConfigVariablesGroupedQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<GetEnvironmentVariablesGroupedQuery, GetEnvironmentVariablesGroupedQueryVariables>(GetEnvironmentVariablesGroupedDocument, options);
return Apollo.useLazyQuery<GetConfigVariablesGroupedQuery, GetConfigVariablesGroupedQueryVariables>(GetConfigVariablesGroupedDocument, options);
}
export type GetEnvironmentVariablesGroupedQueryHookResult = ReturnType<typeof useGetEnvironmentVariablesGroupedQuery>;
export type GetEnvironmentVariablesGroupedLazyQueryHookResult = ReturnType<typeof useGetEnvironmentVariablesGroupedLazyQuery>;
export type GetEnvironmentVariablesGroupedQueryResult = Apollo.QueryResult<GetEnvironmentVariablesGroupedQuery, GetEnvironmentVariablesGroupedQueryVariables>;
export type GetConfigVariablesGroupedQueryHookResult = ReturnType<typeof useGetConfigVariablesGroupedQuery>;
export type GetConfigVariablesGroupedLazyQueryHookResult = ReturnType<typeof useGetConfigVariablesGroupedLazyQuery>;
export type GetConfigVariablesGroupedQueryResult = Apollo.QueryResult<GetConfigVariablesGroupedQuery, GetConfigVariablesGroupedQueryVariables>;
export const GetVersionInfoDocument = gql`
query GetVersionInfo {
versionInfo {

View File

@ -5,10 +5,10 @@ import { SettingsPath } from '@/types/SettingsPath';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { t } from '@lingui/core/macro';
import { useGetEnvironmentVariablesGroupedQuery } from '~/generated/graphql';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
import { Card, Section } from 'twenty-ui/layout';
import { H2Title, IconHeartRateMonitor } from 'twenty-ui/display';
import { Card, Section } from 'twenty-ui/layout';
import { useGetConfigVariablesGroupedQuery } from '~/generated/graphql';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
const StyledGroupContainer = styled.div``;
@ -22,17 +22,17 @@ const StyledCard = styled(Card)`
export const SettingsAdminEnvVariables = () => {
const theme = useTheme();
const { data: environmentVariables, loading: environmentVariablesLoading } =
useGetEnvironmentVariablesGroupedQuery({
const { data: configVariables, loading: configVariablesLoading } =
useGetConfigVariablesGroupedQuery({
fetchPolicy: 'network-only',
});
const visibleGroups =
environmentVariables?.getEnvironmentVariablesGrouped.groups.filter(
configVariables?.getConfigVariablesGrouped.groups.filter(
(group) => !group.isHiddenOnLoad,
) ?? [];
if (environmentVariablesLoading) {
if (configVariablesLoading) {
return <SettingsAdminTabSkeletonLoader />;
}

View File

@ -6,16 +6,16 @@ import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { motion } from 'framer-motion';
import { useState } from 'react';
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
import { IconChevronRight, IconEye, IconEyeOff } from 'twenty-ui/display';
import { LightIconButton } from 'twenty-ui/input';
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
type SettingsAdminEnvVariablesRowProps = {
variable: {
name: string;
description: string;
value: string;
sensitive: boolean;
isSensitive: boolean;
};
isExpanded: boolean;
onExpandToggle: (name: string) => void;
@ -79,7 +79,7 @@ export const SettingsAdminEnvVariablesRow = ({
const displayValue =
variable.value === ''
? 'null'
: variable.sensitive && !showSensitiveValue
: variable.isSensitive && !showSensitiveValue
? '••••••'
: variable.value;
@ -112,7 +112,7 @@ export const SettingsAdminEnvVariablesRow = ({
displayText={displayValue}
multiline={true}
/>
{variable.sensitive && variable.value !== '' && (
{variable.isSensitive && variable.value !== '' && (
<LightIconButton
Icon={showSensitiveValue ? IconEyeOff : IconEye}
size="small"

View File

@ -15,7 +15,7 @@ type SettingsAdminEnvVariablesTableProps = {
name: string;
description: string;
value: string;
sensitive: boolean;
isSensitive: boolean;
}>;
};

View File

@ -1,8 +1,8 @@
import { gql } from '@apollo/client';
export const GET_ENVIRONMENT_VARIABLES_GROUPED = gql`
query GetEnvironmentVariablesGrouped {
getEnvironmentVariablesGrouped {
export const GET_CONFIG_VARIABLES_GROUPED = gql`
query GetConfigVariablesGrouped {
getConfigVariablesGrouped {
groups {
name
description
@ -11,7 +11,7 @@ export const GET_ENVIRONMENT_VARIABLES_GROUPED = gql`
name
description
value
sensitive
isSensitive
}
}
}

View File

@ -5,24 +5,26 @@ import { SettingsPath } from '@/types/SettingsPath';
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
import styled from '@emotion/styled';
import { t } from '@lingui/core/macro';
import { useGetEnvironmentVariablesGroupedQuery } from '~/generated/graphql';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
import { H2Title } from 'twenty-ui/display';
import { useGetConfigVariablesGroupedQuery } from '~/generated/graphql';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
const StyledGroupContainer = styled.div``;
export const SettingsAdminSecondaryEnvVariables = () => {
const { data: environmentVariables, loading: environmentVariablesLoading } =
useGetEnvironmentVariablesGroupedQuery({
fetchPolicy: 'network-only',
});
const {
data: secondaryConfigVariables,
loading: secondaryConfigVariablesLoading,
} = useGetConfigVariablesGroupedQuery({
fetchPolicy: 'network-only',
});
const hiddenGroups =
environmentVariables?.getEnvironmentVariablesGrouped.groups.filter(
secondaryConfigVariables?.getConfigVariablesGrouped.groups.filter(
(group) => group.isHiddenOnLoad,
) ?? [];
if (environmentVariablesLoading) {
if (secondaryConfigVariablesLoading) {
return <SettingsSkeletonLoader />;
}

View File

@ -1,6 +1,6 @@
import { JestConfigWithTsJest, pathsToModuleNameMapper } from 'ts-jest';
import { NodeEnvironment } from 'src/engine/core-modules/environment/interfaces/node-environment.interface';
import { NodeEnvironment } from 'src/engine/core-modules/twenty-config/interfaces/node-environment.interface';
const isBillingEnabled = process.env.IS_BILLING_ENABLED === 'true';

View File

@ -6,8 +6,8 @@ import { EachTestingContext } from 'twenty-shared/testing';
import { Repository } from 'typeorm';
import { UpgradeCommandRunner } from 'src/database/commands/command-runners/upgrade.command-runner';
import { EnvironmentVariables } from 'src/engine/core-modules/environment/environment-variables';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { ConfigVariables } from 'src/engine/core-modules/twenty-config/config-variables';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { SyncWorkspaceMetadataCommand } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command';
@ -97,20 +97,18 @@ const buildUpgradeCommandModule = async ({
},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest
.fn()
.mockImplementation((key: keyof EnvironmentVariables) => {
switch (key) {
case 'APP_VERSION': {
return appVersion;
}
default: {
return;
}
get: jest.fn().mockImplementation((key: keyof ConfigVariables) => {
switch (key) {
case 'APP_VERSION': {
return appVersion;
}
}),
default: {
return;
}
}
}),
},
},
{

View File

@ -9,7 +9,7 @@ import {
ActiveOrSuspendedWorkspacesMigrationCommandRunner,
RunOnWorkspaceArgs,
} from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { SyncWorkspaceMetadataCommand } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command';
@ -26,7 +26,7 @@ export abstract class UpgradeCommandRunner extends ActiveOrSuspendedWorkspacesMi
constructor(
@InjectRepository(Workspace, 'core')
protected readonly workspaceRepository: Repository<Workspace>,
protected readonly environmentService: EnvironmentService,
protected readonly twentyConfigService: TwentyConfigService,
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
protected readonly syncWorkspaceMetadataCommand: SyncWorkspaceMetadataCommand,
) {
@ -87,7 +87,7 @@ export abstract class UpgradeCommandRunner extends ActiveOrSuspendedWorkspacesMi
}
private retrieveToVersionFromAppVersion() {
const appVersion = this.environmentService.get('APP_VERSION');
const appVersion = this.twentyConfigService.get('APP_VERSION');
if (!isDefined(appVersion)) {
throw new Error(

View File

@ -2,14 +2,14 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { DataSeedDemoWorkspaceService } from 'src/database/commands/data-seed-demo-workspace/services/data-seed-demo-workspace.service';
import { EnvironmentModule } from 'src/engine/core-modules/environment/environment.module';
import { TwentyConfigModule } from 'src/engine/core-modules/twenty-config/twenty-config.module';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module';
@Module({
imports: [
WorkspaceManagerModule,
EnvironmentModule,
TwentyConfigModule,
TypeOrmModule.forFeature([Workspace], 'core'),
],
providers: [DataSeedDemoWorkspaceService],

View File

@ -9,7 +9,7 @@ import { rawDataSource } from 'src/database/typeorm/raw/raw.datasource';
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service';
@ -21,7 +21,7 @@ export class DataSeedDemoWorkspaceService {
protected readonly workspaceRepository: Repository<Workspace>,
@InjectCacheStorage(CacheStorageNamespace.EngineWorkspace)
private readonly workspaceSchemaCache: CacheStorageService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {}
async seedDemo(): Promise<void> {
@ -43,7 +43,7 @@ export class DataSeedDemoWorkspaceService {
await deleteCoreSchema(rawDataSource, workspaceId);
}
const appVersion = this.environmentService.get('APP_VERSION');
const appVersion = this.twentyConfigService.get('APP_VERSION');
await seedCoreSchema({
workspaceDataSource: rawDataSource,

View File

@ -32,7 +32,7 @@ import { TypeORMService } from 'src/database/typeorm/typeorm.service';
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity';
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service';
@ -68,7 +68,7 @@ export class DataSeedWorkspaceCommand extends CommandRunner {
private readonly workspaceSchemaCache: CacheStorageService,
private readonly seederService: SeederService,
private readonly workspaceManagerService: WorkspaceManagerService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {
super();
}
@ -94,8 +94,8 @@ export class DataSeedWorkspaceCommand extends CommandRunner {
await rawDataSource.initialize();
const isBillingEnabled = this.environmentService.get('IS_BILLING_ENABLED');
const appVersion = this.environmentService.get('APP_VERSION');
const isBillingEnabled = this.twentyConfigService.get('IS_BILLING_ENABLED');
const appVersion = this.twentyConfigService.get('APP_VERSION');
await seedCoreSchema({
workspaceDataSource: rawDataSource,

View File

@ -17,7 +17,7 @@ import { UpdateDefaultViewRecordOpeningOnWorkflowObjectsCommand } from 'src/data
import { InitializePermissionsCommand } from 'src/database/commands/upgrade-version-command/0-44/0-44-initialize-permissions.command';
import { UpdateViewAggregateOperationsCommand } from 'src/database/commands/upgrade-version-command/0-44/0-44-update-view-aggregate-operations.command';
import { UpgradeCreatedByEnumCommand } from 'src/database/commands/upgrade-version-command/0-51/0-51-update-workflow-trigger-type-enum.command';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { SyncWorkspaceMetadataCommand } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command';
@ -37,7 +37,7 @@ export class UpgradeCommand extends UpgradeCommandRunner {
constructor(
@InjectRepository(Workspace, 'core')
protected readonly workspaceRepository: Repository<Workspace>,
protected readonly environmentService: EnvironmentService,
protected readonly twentyConfigService: TwentyConfigService,
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
protected readonly syncWorkspaceMetadataCommand: SyncWorkspaceMetadataCommand,
@ -57,7 +57,7 @@ export class UpgradeCommand extends UpgradeCommandRunner {
) {
super(
workspaceRepository,
environmentService,
twentyConfigService,
twentyORMGlobalManager,
syncWorkspaceMetadataCommand,
);

View File

@ -2,7 +2,7 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm';
import { typeORMCoreModuleOptions } from 'src/database/typeorm/core/core.datasource';
import { EnvironmentModule } from 'src/engine/core-modules/environment/environment.module';
import { TwentyConfigModule } from 'src/engine/core-modules/twenty-config/twenty-config.module';
import { TypeORMService } from './typeorm.service';
@ -28,7 +28,7 @@ const coreTypeORMFactory = async (): Promise<TypeOrmModuleOptions> => ({
useFactory: coreTypeORMFactory,
name: 'core',
}),
EnvironmentModule,
TwentyConfigModule,
],
providers: [TypeORMService],
exports: [TypeORMService],

View File

@ -2,7 +2,7 @@ import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { DataSource } from 'typeorm';
import { NodeEnvironment } from 'src/engine/core-modules/environment/interfaces/node-environment.interface';
import { NodeEnvironment } from 'src/engine/core-modules/twenty-config/interfaces/node-environment.interface';
import { AppToken } from 'src/engine/core-modules/app-token/app-token.entity';
import { ApprovedAccessDomain } from 'src/engine/core-modules/approved-access-domain/approved-access-domain.entity';
@ -13,11 +13,11 @@ import { BillingPrice } from 'src/engine/core-modules/billing/entities/billing-p
import { BillingProduct } from 'src/engine/core-modules/billing/entities/billing-product.entity';
import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity';
import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { KeyValuePair } from 'src/engine/core-modules/key-value-pair/key-value-pair.entity';
import { PostgresCredentials } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.entity';
import { WorkspaceSSOIdentityProvider } from 'src/engine/core-modules/sso/workspace-sso-identity-provider.entity';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { TwoFactorMethod } from 'src/engine/core-modules/two-factor-method/two-factor-method.entity';
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { User } from 'src/engine/core-modules/user/user.entity';
@ -29,12 +29,12 @@ export class TypeORMService implements OnModuleInit, OnModuleDestroy {
private dataSources: Map<string, DataSource> = new Map();
private isDatasourceInitializing: Map<string, boolean> = new Map();
constructor(private readonly environmentService: EnvironmentService) {
constructor(private readonly twentyConfigService: TwentyConfigService) {
this.mainDataSource = new DataSource({
url: environmentService.get('PG_DATABASE_URL'),
url: twentyConfigService.get('PG_DATABASE_URL'),
type: 'postgres',
logging:
environmentService.get('NODE_ENV') === NodeEnvironment.development
twentyConfigService.get('NODE_ENV') === NodeEnvironment.development
? ['query', 'error']
: ['error'],
schema: 'core',
@ -58,7 +58,7 @@ export class TypeORMService implements OnModuleInit, OnModuleDestroy {
TwoFactorMethod,
],
metadataTableName: '_typeorm_generated_columns_and_materialized_views',
ssl: environmentService.get('PG_SSL_ALLOW_SELF_SIGNED')
ssl: twentyConfigService.get('PG_SSL_ALLOW_SELF_SIGNED')
? {
rejectUnauthorized: false,
}
@ -111,14 +111,14 @@ export class TypeORMService implements OnModuleInit, OnModuleDestroy {
const schema = dataSource.schema;
const workspaceDataSource = new DataSource({
url: dataSource.url ?? this.environmentService.get('PG_DATABASE_URL'),
url: dataSource.url ?? this.twentyConfigService.get('PG_DATABASE_URL'),
type: 'postgres',
logging:
this.environmentService.get('NODE_ENV') === NodeEnvironment.development
this.twentyConfigService.get('NODE_ENV') === NodeEnvironment.development
? ['query', 'error']
: ['error'],
schema,
ssl: this.environmentService.get('PG_SSL_ALLOW_SELF_SIGNED')
ssl: this.twentyConfigService.get('PG_SSL_ALLOW_SELF_SIGNED')
? {
rejectUnauthorized: false,
}

View File

@ -12,16 +12,16 @@ import GraphQLJSON from 'graphql-type-json';
import { GraphQLSchemaWithContext, YogaInitialContext } from 'graphql-yoga';
import { JsonWebTokenError, TokenExpiredError } from 'jsonwebtoken';
import { NodeEnvironment } from 'src/engine/core-modules/environment/interfaces/node-environment.interface';
import { NodeEnvironment } from 'src/engine/core-modules/twenty-config/interfaces/node-environment.interface';
import { useThrottler } from 'src/engine/api/graphql/graphql-config/hooks/use-throttler';
import { WorkspaceSchemaFactory } from 'src/engine/api/graphql/workspace-schema.factory';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { CoreEngineModule } from 'src/engine/core-modules/core-engine.module';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
import { useSentryTracing } from 'src/engine/core-modules/exception-handler/hooks/use-sentry-tracing';
import { useGraphQLErrorHandlerHook } from 'src/engine/core-modules/graphql/hooks/use-graphql-error-handler.hook';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { User } from 'src/engine/core-modules/user/user.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { handleExceptionAndConvertToGraphQLError } from 'src/engine/utils/global-exception-handler.util';
@ -38,17 +38,17 @@ export class GraphQLConfigService
{
constructor(
private readonly exceptionHandlerService: ExceptionHandlerService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly moduleRef: ModuleRef,
) {}
createGqlOptions(): YogaDriverConfig {
const isDebugMode =
this.environmentService.get('NODE_ENV') === NodeEnvironment.development;
this.twentyConfigService.get('NODE_ENV') === NodeEnvironment.development;
const plugins = [
useThrottler({
ttl: this.environmentService.get('API_RATE_LIMITING_TTL'),
limit: this.environmentService.get('API_RATE_LIMITING_LIMIT'),
ttl: this.twentyConfigService.get('API_RATE_LIMITING_TTL'),
limit: this.twentyConfigService.get('API_RATE_LIMITING_LIMIT'),
identifyFn: (context) => {
return context.req.user?.id ?? context.req.ip ?? 'anonymous';
},

View File

@ -5,11 +5,11 @@ import { YogaDriver, YogaDriverConfig } from '@graphql-yoga/nestjs';
import { GraphQLConfigModule } from 'src/engine/api/graphql/graphql-config/graphql-config.module';
import { metadataModuleFactory } from 'src/engine/api/graphql/metadata.module-factory';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { DataloaderModule } from 'src/engine/dataloaders/dataloader.module';
import { DataloaderService } from 'src/engine/dataloaders/dataloader.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
import { MetadataEngineModule } from 'src/engine/metadata-modules/metadata-engine.module';
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module';
@ -21,7 +21,7 @@ import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/wor
useFactory: metadataModuleFactory,
imports: [GraphQLConfigModule, DataloaderModule],
inject: [
EnvironmentService,
TwentyConfigService,
ExceptionHandlerService,
DataloaderService,
CacheStorageNamespace.EngineWorkspace,

View File

@ -1,20 +1,20 @@
import { YogaDriverConfig } from '@graphql-yoga/nestjs';
import GraphQLJSON from 'graphql-type-json';
import { NodeEnvironment } from 'src/engine/core-modules/environment/interfaces/node-environment.interface';
import { NodeEnvironment } from 'src/engine/core-modules/twenty-config/interfaces/node-environment.interface';
import { useCachedMetadata } from 'src/engine/api/graphql/graphql-config/hooks/use-cached-metadata';
import { useThrottler } from 'src/engine/api/graphql/graphql-config/hooks/use-throttler';
import { MetadataGraphQLApiModule } from 'src/engine/api/graphql/metadata-graphql-api.module';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
import { useGraphQLErrorHandlerHook } from 'src/engine/core-modules/graphql/hooks/use-graphql-error-handler.hook';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { DataloaderService } from 'src/engine/dataloaders/dataloader.service';
import { renderApolloPlayground } from 'src/engine/utils/render-apollo-playground.util';
export const metadataModuleFactory = async (
environmentService: EnvironmentService,
twentyConfigService: TwentyConfigService,
exceptionHandlerService: ExceptionHandlerService,
dataloaderService: DataloaderService,
cacheStorageService: CacheStorageService,
@ -28,8 +28,8 @@ export const metadataModuleFactory = async (
resolvers: { JSON: GraphQLJSON },
plugins: [
useThrottler({
ttl: environmentService.get('API_RATE_LIMITING_TTL'),
limit: environmentService.get('API_RATE_LIMITING_LIMIT'),
ttl: twentyConfigService.get('API_RATE_LIMITING_TTL'),
limit: twentyConfigService.get('API_RATE_LIMITING_LIMIT'),
identifyFn: (context) => {
return context.req.user?.id ?? context.req.ip ?? 'anonymous';
},
@ -49,7 +49,7 @@ export const metadataModuleFactory = async (
}),
};
if (environmentService.get('NODE_ENV') === NodeEnvironment.development) {
if (twentyConfigService.get('NODE_ENV') === NodeEnvironment.development) {
config.renderGraphiQL = () => {
return renderApolloPlayground({ path: 'metadata' });
};

View File

@ -1,13 +1,13 @@
import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { Injectable } from '@nestjs/common';
import { Request } from 'express';
import { AxiosResponse } from 'axios';
import { Request } from 'express';
import { Query } from 'src/engine/api/rest/core/types/query.type';
import { getServerUrl } from 'src/utils/get-server-url';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { RestApiException } from 'src/engine/api/rest/errors/RestApiException';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { getServerUrl } from 'src/utils/get-server-url';
export enum GraphqlApiType {
CORE = 'core',
@ -17,14 +17,14 @@ export enum GraphqlApiType {
@Injectable()
export class RestApiService {
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly httpService: HttpService,
) {}
async call(graphqlApiType: GraphqlApiType, request: Request, data: Query) {
const baseUrl = getServerUrl(
request,
this.environmentService.get('SERVER_URL'),
this.twentyConfigService.get('SERVER_URL'),
);
let response: AxiosResponse;
const url = `${baseUrl}/${

View File

@ -8,7 +8,6 @@ import { HEALTH_INDICATORS } from 'src/engine/core-modules/admin-panel/constants
import { SystemHealth } from 'src/engine/core-modules/admin-panel/dtos/system-health.dto';
import { AdminPanelHealthServiceStatus } from 'src/engine/core-modules/admin-panel/enums/admin-panel-health-service-status.enum';
import { QueueMetricsTimeRange } from 'src/engine/core-modules/admin-panel/enums/queue-metrics-time-range.enum';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { HEALTH_ERROR_MESSAGES } from 'src/engine/core-modules/health/constants/health-error-messages.constants';
import { HealthIndicatorId } from 'src/engine/core-modules/health/enums/health-indicator-id.enum';
import { AppHealthIndicator } from 'src/engine/core-modules/health/indicators/app.health';
@ -18,6 +17,7 @@ import { RedisHealthIndicator } from 'src/engine/core-modules/health/indicators/
import { WorkerHealthIndicator } from 'src/engine/core-modules/health/indicators/worker.health';
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
import { RedisClientService } from 'src/engine/core-modules/redis-client/redis-client.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
jest.mock('bullmq');
@ -29,7 +29,7 @@ describe('AdminPanelHealthService', () => {
let connectedAccountHealth: jest.Mocked<ConnectedAccountHealth>;
let appHealth: jest.Mocked<AppHealthIndicator>;
let redisClient: jest.Mocked<RedisClientService>;
let environmentService: jest.Mocked<EnvironmentService>;
let twentyConfigService: jest.Mocked<TwentyConfigService>;
let loggerSpy: jest.SpyInstance;
beforeEach(async () => {
@ -41,7 +41,7 @@ describe('AdminPanelHealthService', () => {
redisClient = {
getClient: jest.fn().mockReturnValue({} as Redis),
} as any;
environmentService = { get: jest.fn() } as any;
twentyConfigService = { get: jest.fn() } as any;
(Queue as unknown as jest.Mock) = jest.fn().mockImplementation(() => ({
getMetrics: jest.fn(),
@ -58,7 +58,7 @@ describe('AdminPanelHealthService', () => {
{ provide: ConnectedAccountHealth, useValue: connectedAccountHealth },
{ provide: AppHealthIndicator, useValue: appHealth },
{ provide: RedisClientService, useValue: redisClient },
{ provide: EnvironmentService, useValue: environmentService },
{ provide: TwentyConfigService, useValue: twentyConfigService },
],
}).compile();

View File

@ -10,17 +10,17 @@ import {
} from 'src/engine/core-modules/auth/auth.exception';
import { LoginTokenService } from 'src/engine/core-modules/auth/token/services/login-token.service';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { User } from 'src/engine/core-modules/user/user.entity';
const UserFindOneMock = jest.fn();
const LoginTokenServiceGenerateLoginTokenMock = jest.fn();
const EnvironmentServiceGetAllMock = jest.fn();
const TwentyConfigServiceGetAllMock = jest.fn();
jest.mock(
'../../environment/constants/environment-variables-group-metadata',
'src/engine/core-modules/twenty-config/constants/config-variables-group-metadata',
() => ({
ENVIRONMENT_VARIABLES_GROUP_METADATA: {
CONFIG_VARIABLES_GROUP_METADATA: {
SERVER_CONFIG: {
position: 100,
description: 'Server config description',
@ -69,9 +69,9 @@ describe('AdminPanelService', () => {
},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
getAll: EnvironmentServiceGetAllMock,
getAll: TwentyConfigServiceGetAllMock,
},
},
],
@ -157,9 +157,9 @@ describe('AdminPanelService', () => {
expect(UserFindOneMock).toHaveBeenCalled();
});
describe('getEnvironmentVariablesGrouped', () => {
it('should correctly group and sort environment variables', () => {
EnvironmentServiceGetAllMock.mockReturnValue({
describe('getConfigVariablesGrouped', () => {
it('should correctly group and sort config variables', () => {
TwentyConfigServiceGetAllMock.mockReturnValue({
SERVER_URL: {
value: 'http://localhost',
metadata: {
@ -179,7 +179,7 @@ describe('AdminPanelService', () => {
metadata: {
group: 'SERVER_CONFIG',
description: 'API Key',
sensitive: true,
isSensitive: true,
},
},
OTHER_VAR: {
@ -191,7 +191,7 @@ describe('AdminPanelService', () => {
},
});
const result = service.getEnvironmentVariablesGrouped();
const result = service.getConfigVariablesGrouped();
expect(result).toEqual({
groups: [
@ -204,13 +204,13 @@ describe('AdminPanelService', () => {
name: 'API_KEY',
value: 'secret-key',
description: 'API Key',
sensitive: true,
isSensitive: true,
},
{
name: 'SERVER_URL',
value: 'http://localhost',
description: 'Server URL',
sensitive: false,
isSensitive: false,
},
],
},
@ -223,7 +223,7 @@ describe('AdminPanelService', () => {
name: 'RATE_LIMIT_TTL',
value: '60',
description: 'Rate limit TTL',
sensitive: false,
isSensitive: false,
},
],
},
@ -236,7 +236,7 @@ describe('AdminPanelService', () => {
name: 'OTHER_VAR',
value: 'other',
description: 'Other var',
sensitive: false,
isSensitive: false,
},
],
},
@ -248,10 +248,10 @@ describe('AdminPanelService', () => {
expect(result.groups[2].name).toBe('OTHER');
});
it('should handle empty environment variables', () => {
EnvironmentServiceGetAllMock.mockReturnValue({});
it('should handle empty config variables', () => {
TwentyConfigServiceGetAllMock.mockReturnValue({});
const result = service.getEnvironmentVariablesGrouped();
const result = service.getConfigVariablesGrouped();
expect(result).toEqual({
groups: [],
@ -259,7 +259,7 @@ describe('AdminPanelService', () => {
});
it('should handle variables with undefined metadata fields', () => {
EnvironmentServiceGetAllMock.mockReturnValue({
TwentyConfigServiceGetAllMock.mockReturnValue({
TEST_VAR: {
value: 'test',
metadata: {
@ -268,13 +268,13 @@ describe('AdminPanelService', () => {
},
});
const result = service.getEnvironmentVariablesGrouped();
const result = service.getConfigVariablesGrouped();
expect(result.groups[0].variables[0]).toEqual({
name: 'TEST_VAR',
value: 'test',
description: undefined,
sensitive: false,
isSensitive: false,
});
});
});
@ -287,7 +287,7 @@ describe('AdminPanelService', () => {
mockEnvironmentGet.mockReset();
mockAxiosGet.mockReset();
jest.spyOn(axios, 'get').mockImplementation(mockAxiosGet);
service['environmentService'].get = mockEnvironmentGet;
service['twentyConfigService'].get = mockEnvironmentGet;
});
it('should return current and latest version when everything works', async () => {

View File

@ -3,7 +3,7 @@ import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
import { AdminPanelHealthService } from 'src/engine/core-modules/admin-panel/admin-panel-health.service';
import { AdminPanelService } from 'src/engine/core-modules/admin-panel/admin-panel.service';
import { EnvironmentVariablesOutput } from 'src/engine/core-modules/admin-panel/dtos/environment-variables.output';
import { ConfigVariablesOutput } from 'src/engine/core-modules/admin-panel/dtos/config-variables.output';
import { ImpersonateInput } from 'src/engine/core-modules/admin-panel/dtos/impersonate.input';
import { ImpersonateOutput } from 'src/engine/core-modules/admin-panel/dtos/impersonate.output';
import { SystemHealth } from 'src/engine/core-modules/admin-panel/dtos/system-health.dto';
@ -17,7 +17,6 @@ import { FeatureFlagException } from 'src/engine/core-modules/feature-flag/featu
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
import { HealthIndicatorId } from 'src/engine/core-modules/health/enums/health-indicator-id.enum';
import { WorkerHealthIndicator } from 'src/engine/core-modules/health/indicators/worker.health';
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
import { AdminPanelGuard } from 'src/engine/guards/admin-panel-guard';
import { ImpersonateGuard } from 'src/engine/guards/impersonate-guard';
@ -33,7 +32,6 @@ export class AdminPanelResolver {
constructor(
private adminService: AdminPanelService,
private adminPanelHealthService: AdminPanelHealthService,
private workerHealthIndicator: WorkerHealthIndicator,
private featureFlagService: FeatureFlagService,
) {}
@ -76,9 +74,9 @@ export class AdminPanelResolver {
}
@UseGuards(WorkspaceAuthGuard, UserAuthGuard, AdminPanelGuard)
@Query(() => EnvironmentVariablesOutput)
async getEnvironmentVariablesGrouped(): Promise<EnvironmentVariablesOutput> {
return this.adminService.getEnvironmentVariablesGrouped();
@Query(() => ConfigVariablesOutput)
async getConfigVariablesGrouped(): Promise<ConfigVariablesOutput> {
return this.adminService.getConfigVariablesGrouped();
}
@UseGuards(WorkspaceAuthGuard, UserAuthGuard, AdminPanelGuard)

View File

@ -5,9 +5,9 @@ import axios from 'axios';
import semver from 'semver';
import { Repository } from 'typeorm';
import { EnvironmentVariable } from 'src/engine/core-modules/admin-panel/dtos/environment-variable.dto';
import { EnvironmentVariablesGroupData } from 'src/engine/core-modules/admin-panel/dtos/environment-variables-group.dto';
import { EnvironmentVariablesOutput } from 'src/engine/core-modules/admin-panel/dtos/environment-variables.output';
import { ConfigVariable } from 'src/engine/core-modules/admin-panel/dtos/config-variable.dto';
import { ConfigVariablesGroupData } from 'src/engine/core-modules/admin-panel/dtos/config-variables-group.dto';
import { ConfigVariablesOutput } from 'src/engine/core-modules/admin-panel/dtos/config-variables.output';
import { UserLookup } from 'src/engine/core-modules/admin-panel/dtos/user-lookup.entity';
import { VersionInfo } from 'src/engine/core-modules/admin-panel/dtos/version-info.dto';
import {
@ -16,11 +16,11 @@ import {
} from 'src/engine/core-modules/auth/auth.exception';
import { LoginTokenService } from 'src/engine/core-modules/auth/token/services/login-token.service';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { ENVIRONMENT_VARIABLES_GROUP_METADATA } from 'src/engine/core-modules/environment/constants/environment-variables-group-metadata';
import { EnvironmentVariablesGroup } from 'src/engine/core-modules/environment/enums/environment-variables-group.enum';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { CONFIG_VARIABLES_GROUP_METADATA } from 'src/engine/core-modules/twenty-config/constants/config-variables-group-metadata';
import { ConfigVariablesGroup } from 'src/engine/core-modules/twenty-config/enums/config-variables-group.enum';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { User } from 'src/engine/core-modules/user/user.entity';
import { userValidator } from 'src/engine/core-modules/user/user.validate';
@ -28,7 +28,7 @@ import { userValidator } from 'src/engine/core-modules/user/user.validate';
export class AdminPanelService {
constructor(
private readonly loginTokenService: LoginTokenService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly domainManagerService: DomainManagerService,
@InjectRepository(User, 'core')
private readonly userRepository: Repository<User>,
@ -123,21 +123,18 @@ export class AdminPanelService {
};
}
getEnvironmentVariablesGrouped(): EnvironmentVariablesOutput {
const rawEnvVars = this.environmentService.getAll();
const groupedData = new Map<
EnvironmentVariablesGroup,
EnvironmentVariable[]
>();
getConfigVariablesGrouped(): ConfigVariablesOutput {
const rawEnvVars = this.twentyConfigService.getAll();
const groupedData = new Map<ConfigVariablesGroup, ConfigVariable[]>();
for (const [varName, { value, metadata }] of Object.entries(rawEnvVars)) {
const { group, description } = metadata;
const envVar: EnvironmentVariable = {
const envVar: ConfigVariable = {
name: varName,
description,
value: String(value),
sensitive: metadata.sensitive ?? false,
isSensitive: metadata.isSensitive ?? false,
};
if (!groupedData.has(group)) {
@ -147,20 +144,17 @@ export class AdminPanelService {
groupedData.get(group)?.push(envVar);
}
const groups: EnvironmentVariablesGroupData[] = Array.from(
groupedData.entries(),
)
const groups: ConfigVariablesGroupData[] = Array.from(groupedData.entries())
.sort((a, b) => {
const positionA = ENVIRONMENT_VARIABLES_GROUP_METADATA[a[0]].position;
const positionB = ENVIRONMENT_VARIABLES_GROUP_METADATA[b[0]].position;
const positionA = CONFIG_VARIABLES_GROUP_METADATA[a[0]].position;
const positionB = CONFIG_VARIABLES_GROUP_METADATA[b[0]].position;
return positionA - positionB;
})
.map(([name, variables]) => ({
name,
description: ENVIRONMENT_VARIABLES_GROUP_METADATA[name].description,
isHiddenOnLoad:
ENVIRONMENT_VARIABLES_GROUP_METADATA[name].isHiddenOnLoad,
description: CONFIG_VARIABLES_GROUP_METADATA[name].description,
isHiddenOnLoad: CONFIG_VARIABLES_GROUP_METADATA[name].isHiddenOnLoad,
variables: variables.sort((a, b) => a.name.localeCompare(b.name)),
}));
@ -168,7 +162,7 @@ export class AdminPanelService {
}
async getVersionInfo(): Promise<VersionInfo> {
const currentVersion = this.environmentService.get('APP_VERSION');
const currentVersion = this.twentyConfigService.get('APP_VERSION');
try {
const response = await axios.get(

View File

@ -1,7 +1,7 @@
import { Field, ObjectType } from '@nestjs/graphql';
@ObjectType()
export class EnvironmentVariable {
export class ConfigVariable {
@Field()
name: string;
@ -12,5 +12,5 @@ export class EnvironmentVariable {
value: string;
@Field()
sensitive: boolean;
isSensitive: boolean;
}

View File

@ -0,0 +1,23 @@
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
import { ConfigVariable } from 'src/engine/core-modules/admin-panel/dtos/config-variable.dto';
import { ConfigVariablesGroup } from 'src/engine/core-modules/twenty-config/enums/config-variables-group.enum';
registerEnumType(ConfigVariablesGroup, {
name: 'ConfigVariablesGroup',
});
@ObjectType()
export class ConfigVariablesGroupData {
@Field(() => [ConfigVariable])
variables: ConfigVariable[];
@Field(() => ConfigVariablesGroup)
name: ConfigVariablesGroup;
@Field(() => String, { defaultValue: '' })
description: string;
@Field(() => Boolean, { defaultValue: false })
isHiddenOnLoad: boolean;
}

View File

@ -0,0 +1,9 @@
import { Field, ObjectType } from '@nestjs/graphql';
import { ConfigVariablesGroupData } from 'src/engine/core-modules/admin-panel/dtos/config-variables-group.dto';
@ObjectType()
export class ConfigVariablesOutput {
@Field(() => [ConfigVariablesGroupData])
groups: ConfigVariablesGroupData[];
}

View File

@ -1,24 +0,0 @@
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
import { EnvironmentVariablesGroup } from 'src/engine/core-modules/environment/enums/environment-variables-group.enum';
import { EnvironmentVariable } from './environment-variable.dto';
registerEnumType(EnvironmentVariablesGroup, {
name: 'EnvironmentVariablesGroup',
});
@ObjectType()
export class EnvironmentVariablesGroupData {
@Field(() => [EnvironmentVariable])
variables: EnvironmentVariable[];
@Field(() => EnvironmentVariablesGroup)
name: EnvironmentVariablesGroup;
@Field(() => String, { defaultValue: '' })
description: string;
@Field(() => Boolean, { defaultValue: false })
isHiddenOnLoad: boolean;
}

View File

@ -1,9 +0,0 @@
import { Field, ObjectType } from '@nestjs/graphql';
import { EnvironmentVariablesGroupData } from './environment-variables-group.dto';
@ObjectType()
export class EnvironmentVariablesOutput {
@Field(() => [EnvironmentVariablesGroupData])
groups: EnvironmentVariablesGroupData[];
}

View File

@ -1,8 +1,8 @@
import { HttpService } from '@nestjs/axios';
import { Test, TestingModule } from '@nestjs/testing';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { AnalyticsService } from './analytics.service';
@ -14,7 +14,7 @@ describe('AnalyticsService', () => {
providers: [
AnalyticsService,
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {},
},
{

View File

@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
type CreateEventInput = {
action: string;
@ -9,14 +9,14 @@ type CreateEventInput = {
@Injectable()
export class AnalyticsService {
constructor(private readonly environmentService: EnvironmentService) {}
constructor(private readonly twentyConfigService: TwentyConfigService) {}
async create(
createEventInput: CreateEventInput,
userId: string | null | undefined,
workspaceId: string | null | undefined,
) {
if (!this.environmentService.get('ANALYTICS_ENABLED')) {
if (!this.twentyConfigService.get('ANALYTICS_ENABLED')) {
return { success: true };
}

View File

@ -16,7 +16,7 @@ import {
import { approvedAccessDomainValidator } from 'src/engine/core-modules/approved-access-domain/approved-access-domain.validate';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EmailService } from 'src/engine/core-modules/email/email.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { User } from 'src/engine/core-modules/user/user.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { isWorkDomain } from 'src/utils/is-work-email';
@ -28,7 +28,7 @@ export class ApprovedAccessDomainService {
@InjectRepository(ApprovedAccessDomainEntity, 'core')
private readonly approvedAccessDomainRepository: Repository<ApprovedAccessDomainEntity>,
private readonly emailService: EmailService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly domainManagerService: DomainManagerService,
) {}
@ -70,7 +70,7 @@ export class ApprovedAccessDomainService {
firstName: sender.firstName,
lastName: sender.lastName,
},
serverUrl: this.environmentService.get('SERVER_URL'),
serverUrl: this.twentyConfigService.get('SERVER_URL'),
locale: 'en' as keyof typeof APP_LOCALES,
});
const html = await render(emailTemplate);
@ -79,7 +79,7 @@ export class ApprovedAccessDomainService {
});
await this.emailService.send({
from: `${sender.firstName} ${sender.lastName} (via Twenty) <${this.environmentService.get('EMAIL_FROM_ADDRESS')}>`,
from: `${sender.firstName} ${sender.lastName} (via Twenty) <${this.twentyConfigService.get('EMAIL_FROM_ADDRESS')}>`,
to,
subject: 'Approve your access domain',
text,
@ -94,7 +94,7 @@ export class ApprovedAccessDomainService {
JSON.stringify({
id: approvedAccessDomain.id,
domain: approvedAccessDomain.domain,
key: this.environmentService.get('APP_SECRET'),
key: this.twentyConfigService.get('APP_SECRET'),
}),
)
.digest('hex');

View File

@ -3,16 +3,16 @@ import { getRepositoryToken } from '@nestjs/typeorm';
import { DeleteResult, Repository } from 'typeorm';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { User } from 'src/engine/core-modules/user/user.entity';
import { EmailService } from 'src/engine/core-modules/email/email.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { ApprovedAccessDomain } from 'src/engine/core-modules/approved-access-domain/approved-access-domain.entity';
import {
ApprovedAccessDomainException,
ApprovedAccessDomainExceptionCode,
} from 'src/engine/core-modules/approved-access-domain/approved-access-domain.exception';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EmailService } from 'src/engine/core-modules/email/email.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { User } from 'src/engine/core-modules/user/user.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { ApprovedAccessDomainService } from './approved-access-domain.service';
@ -20,7 +20,7 @@ describe('ApprovedAccessDomainService', () => {
let service: ApprovedAccessDomainService;
let approvedAccessDomainRepository: Repository<ApprovedAccessDomain>;
let emailService: EmailService;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
let domainManagerService: DomainManagerService;
beforeEach(async () => {
@ -43,7 +43,7 @@ describe('ApprovedAccessDomainService', () => {
},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -64,7 +64,7 @@ describe('ApprovedAccessDomainService', () => {
getRepositoryToken(ApprovedAccessDomain, 'core'),
);
emailService = module.get<EmailService>(EmailService);
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
domainManagerService =
module.get<DomainManagerService>(DomainManagerService);
});
@ -267,7 +267,7 @@ describe('ApprovedAccessDomainService', () => {
.mockReturnValue(new URL('https://sub.twenty.com'));
jest
.spyOn(environmentService, 'get')
.spyOn(twentyConfigService, 'get')
.mockImplementation((key: string) => {
if (key === 'EMAIL_FROM_ADDRESS') return 'no-reply@example.com';
if (key === 'SERVER_URL') return 'https://api.example.com';

View File

@ -22,9 +22,9 @@ import { GoogleAPIsService } from 'src/engine/core-modules/auth/services/google-
import { TransientTokenService } from 'src/engine/core-modules/auth/token/services/transient-token.service';
import { GoogleAPIsRequest } from 'src/engine/core-modules/auth/types/google-api-request.type';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Controller('auth/google-apis')
@ -33,7 +33,7 @@ export class GoogleAPIsAuthController {
constructor(
private readonly googleAPIsService: GoogleAPIsService,
private readonly transientTokenService: TransientTokenService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly onboardingService: OnboardingService,
private readonly domainManagerService: DomainManagerService,
private readonly guardRedirectService: GuardRedirectService,
@ -123,7 +123,7 @@ export class GoogleAPIsAuthController {
this.guardRedirectService.getRedirectErrorUrlAndCaptureExceptions(
err,
workspace ?? {
subdomain: this.environmentService.get('DEFAULT_SUBDOMAIN'),
subdomain: this.twentyConfigService.get('DEFAULT_SUBDOMAIN'),
customDomain: null,
},
),

View File

@ -22,9 +22,9 @@ import { MicrosoftAPIsService } from 'src/engine/core-modules/auth/services/micr
import { TransientTokenService } from 'src/engine/core-modules/auth/token/services/transient-token.service';
import { MicrosoftAPIsRequest } from 'src/engine/core-modules/auth/types/microsoft-api-request.type';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Controller('auth/microsoft-apis')
@ -33,7 +33,7 @@ export class MicrosoftAPIsAuthController {
constructor(
private readonly microsoftAPIsService: MicrosoftAPIsService,
private readonly transientTokenService: TransientTokenService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly domainManagerService: DomainManagerService,
private readonly onboardingService: OnboardingService,
private readonly guardRedirectService: GuardRedirectService,
@ -130,7 +130,7 @@ export class MicrosoftAPIsAuthController {
this.guardRedirectService.getRedirectErrorUrlAndCaptureExceptions(
err,
workspace ?? {
subdomain: this.environmentService.get('DEFAULT_SUBDOMAIN'),
subdomain: this.twentyConfigService.get('DEFAULT_SUBDOMAIN'),
customDomain: null,
},
),

View File

@ -6,19 +6,19 @@ import {
AuthException,
AuthExceptionCode,
} from 'src/engine/core-modules/auth/auth.exception';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class EnterpriseFeaturesEnabledGuard implements CanActivate {
constructor(
private readonly guardRedirectService: GuardRedirectService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {}
canActivate(context: ExecutionContext): boolean {
try {
if (!this.environmentService.get('ENTERPRISE_KEY')) {
if (!this.twentyConfigService.get('ENTERPRISE_KEY')) {
throw new AuthException(
'Enterprise key missing',
AuthExceptionCode.MISSING_ENVIRONMENT_VARIABLE,

View File

@ -7,8 +7,8 @@ import {
} from 'src/engine/core-modules/auth/auth.exception';
import { GoogleAPIsOauthExchangeCodeForTokenStrategy } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-exchange-code-for-token.auth.strategy';
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class GoogleAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
@ -16,7 +16,7 @@ export class GoogleAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
) {
constructor(
private readonly guardRedirectService: GuardRedirectService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {
super();
}
@ -27,8 +27,8 @@ export class GoogleAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
const state = JSON.parse(request.query.state);
if (
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
!this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
!this.twentyConfigService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
!this.twentyConfigService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
) {
throw new AuthException(
'Google apis auth is not enabled',
@ -36,7 +36,7 @@ export class GoogleAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
);
}
new GoogleAPIsOauthExchangeCodeForTokenStrategy(this.environmentService);
new GoogleAPIsOauthExchangeCodeForTokenStrategy(this.twentyConfigService);
setRequestExtraParams(request, {
transientToken: state.transientToken,

View File

@ -11,15 +11,15 @@ import {
import { GoogleAPIsOauthRequestCodeStrategy } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-request-code.auth.strategy';
import { TransientTokenService } from 'src/engine/core-modules/auth/token/services/transient-token.service';
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Injectable()
export class GoogleAPIsOauthRequestCodeGuard extends AuthGuard('google-apis') {
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly transientTokenService: TransientTokenService,
private readonly guardRedirectService: GuardRedirectService,
@InjectRepository(Workspace, 'core')
@ -57,8 +57,8 @@ export class GoogleAPIsOauthRequestCodeGuard extends AuthGuard('google-apis') {
});
if (
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
!this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
!this.twentyConfigService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
!this.twentyConfigService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
) {
throw new AuthException(
'Google apis auth is not enabled',
@ -66,7 +66,7 @@ export class GoogleAPIsOauthRequestCodeGuard extends AuthGuard('google-apis') {
);
}
new GoogleAPIsOauthRequestCodeStrategy(this.environmentService);
new GoogleAPIsOauthRequestCodeStrategy(this.twentyConfigService);
return (await super.canActivate(context)) as boolean;
} catch (err) {

View File

@ -5,26 +5,26 @@ import {
AuthExceptionCode,
} from 'src/engine/core-modules/auth/auth.exception';
import { GoogleStrategy } from 'src/engine/core-modules/auth/strategies/google.auth.strategy';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class GoogleProviderEnabledGuard implements CanActivate {
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly guardRedirectService: GuardRedirectService,
) {}
canActivate(context: ExecutionContext): boolean {
try {
if (!this.environmentService.get('AUTH_GOOGLE_ENABLED')) {
if (!this.twentyConfigService.get('AUTH_GOOGLE_ENABLED')) {
throw new AuthException(
'Google auth is not enabled',
AuthExceptionCode.GOOGLE_API_AUTH_DISABLED,
);
}
new GoogleStrategy(this.environmentService);
new GoogleStrategy(this.twentyConfigService);
return true;
} catch (err) {

View File

@ -7,8 +7,8 @@ import {
} from 'src/engine/core-modules/auth/auth.exception';
import { MicrosoftAPIsOauthExchangeCodeForTokenStrategy } from 'src/engine/core-modules/auth/strategies/microsoft-apis-oauth-exchange-code-for-token.auth.strategy';
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class MicrosoftAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
@ -16,7 +16,7 @@ export class MicrosoftAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
) {
constructor(
private readonly guardRedirectService: GuardRedirectService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {
super();
}
@ -27,8 +27,8 @@ export class MicrosoftAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
const state = JSON.parse(request.query.state);
if (
!this.environmentService.get('MESSAGING_PROVIDER_MICROSOFT_ENABLED') &&
!this.environmentService.get('CALENDAR_PROVIDER_MICROSOFT_ENABLED')
!this.twentyConfigService.get('MESSAGING_PROVIDER_MICROSOFT_ENABLED') &&
!this.twentyConfigService.get('CALENDAR_PROVIDER_MICROSOFT_ENABLED')
) {
throw new AuthException(
'Microsoft apis auth is not enabled',
@ -37,7 +37,7 @@ export class MicrosoftAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
}
new MicrosoftAPIsOauthExchangeCodeForTokenStrategy(
this.environmentService,
this.twentyConfigService,
);
setRequestExtraParams(request, {

View File

@ -11,17 +11,17 @@ import {
import { MicrosoftAPIsOauthRequestCodeStrategy } from 'src/engine/core-modules/auth/strategies/microsoft-apis-oauth-request-code.auth.strategy';
import { TransientTokenService } from 'src/engine/core-modules/auth/token/services/transient-token.service';
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Injectable()
export class MicrosoftAPIsOauthRequestCodeGuard extends AuthGuard(
'microsoft-apis',
) {
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly transientTokenService: TransientTokenService,
private readonly guardRedirectService: GuardRedirectService,
@InjectRepository(Workspace, 'core')
@ -38,8 +38,8 @@ export class MicrosoftAPIsOauthRequestCodeGuard extends AuthGuard(
try {
if (
!this.environmentService.get('MESSAGING_PROVIDER_MICROSOFT_ENABLED') &&
!this.environmentService.get('CALENDAR_PROVIDER_MICROSOFT_ENABLED')
!this.twentyConfigService.get('MESSAGING_PROVIDER_MICROSOFT_ENABLED') &&
!this.twentyConfigService.get('CALENDAR_PROVIDER_MICROSOFT_ENABLED')
) {
throw new AuthException(
'Microsoft apis auth is not enabled',
@ -58,7 +58,7 @@ export class MicrosoftAPIsOauthRequestCodeGuard extends AuthGuard(
id: workspaceId,
});
new MicrosoftAPIsOauthRequestCodeStrategy(this.environmentService);
new MicrosoftAPIsOauthRequestCodeStrategy(this.twentyConfigService);
setRequestExtraParams(request, {
transientToken: request.query.transientToken,
redirectLocation: request.query.redirectLocation,

View File

@ -5,26 +5,26 @@ import {
AuthExceptionCode,
} from 'src/engine/core-modules/auth/auth.exception';
import { MicrosoftStrategy } from 'src/engine/core-modules/auth/strategies/microsoft.auth.strategy';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class MicrosoftProviderEnabledGuard implements CanActivate {
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly guardRedirectService: GuardRedirectService,
) {}
canActivate(context: ExecutionContext): boolean {
try {
if (!this.environmentService.get('AUTH_MICROSOFT_ENABLED')) {
if (!this.twentyConfigService.get('AUTH_MICROSOFT_ENABLED')) {
throw new AuthException(
'Microsoft auth is not enabled',
AuthExceptionCode.MICROSOFT_API_AUTH_DISABLED,
);
}
new MicrosoftStrategy(this.environmentService);
new MicrosoftStrategy(this.twentyConfigService);
return true;
} catch (err) {

View File

@ -1,14 +1,14 @@
import { Test, TestingModule } from '@nestjs/testing';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { ApiKeyService } from './api-key.service';
describe('ApiKeyService', () => {
let service: ApiKeyService;
let jwtWrapperService: JwtWrapperService;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
@ -22,7 +22,7 @@ describe('ApiKeyService', () => {
},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -32,7 +32,7 @@ describe('ApiKeyService', () => {
service = module.get<ApiKeyService>(ApiKeyService);
jwtWrapperService = module.get<JwtWrapperService>(JwtWrapperService);
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
});
it('should be defined', () => {
@ -51,7 +51,7 @@ describe('ApiKeyService', () => {
const apiKeyId = 'api-key-id';
const mockToken = 'mock-token';
jest.spyOn(environmentService, 'get').mockReturnValue('1h');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('1h');
jest.spyOn(jwtWrapperService, 'sign').mockReturnValue(mockToken);
jest
.spyOn(jwtWrapperService, 'generateAppSecret')

View File

@ -1,14 +1,14 @@
import { Injectable } from '@nestjs/common';
import { ApiKeyToken } from 'src/engine/core-modules/auth/dto/token.entity';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class ApiKeyService {
constructor(
private readonly jwtWrapperService: JwtWrapperService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {}
async generateApiKeyToken(

View File

@ -3,16 +3,16 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { WorkspaceAuthProvider } from 'src/engine/core-modules/workspace/types/workspace.type';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Injectable()
export class AuthSsoService {
constructor(
@InjectRepository(Workspace, 'core')
private readonly workspaceRepository: Repository<Workspace>,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {}
private getAuthProviderColumnNameByProvider(
@ -41,7 +41,7 @@ export class AuthSsoService {
workspaceId?: string,
) {
if (
this.environmentService.get('IS_MULTIWORKSPACE_ENABLED') &&
this.twentyConfigService.get('IS_MULTIWORKSPACE_ENABLED') &&
!workspaceId
) {
// Multi-workspace enable mode but on non workspace url.

View File

@ -4,13 +4,13 @@ import { getRepositoryToken } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { AuthSsoService } from 'src/engine/core-modules/auth/services/auth-sso.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
describe('AuthSsoService', () => {
let authSsoService: AuthSsoService;
let workspaceRepository: Repository<Workspace>;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
@ -23,7 +23,7 @@ describe('AuthSsoService', () => {
},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -35,7 +35,7 @@ describe('AuthSsoService', () => {
workspaceRepository = module.get<Repository<Workspace>>(
getRepositoryToken(Workspace, 'core'),
);
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
});
describe('findWorkspaceFromWorkspaceIdOrAuthProvider', () => {
@ -67,7 +67,7 @@ describe('AuthSsoService', () => {
const email = 'test@example.com';
const mockWorkspace = { id: 'workspace-id-456' } as Workspace;
jest.spyOn(environmentService, 'get').mockReturnValue(true);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(true);
jest
.spyOn(workspaceRepository, 'findOne')
.mockResolvedValue(mockWorkspace);
@ -97,7 +97,7 @@ describe('AuthSsoService', () => {
});
it('should return undefined if no workspace is found when multi-workspace mode is enabled', async () => {
jest.spyOn(environmentService, 'get').mockReturnValue(true);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(true);
jest.spyOn(workspaceRepository, 'findOne').mockResolvedValue(null);
const result =
@ -110,7 +110,7 @@ describe('AuthSsoService', () => {
});
it('should throw an error for an invalid authProvider', async () => {
jest.spyOn(environmentService, 'get').mockReturnValue(true);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(true);
await expect(
authSsoService.findWorkspaceFromWorkspaceIdOrAuthProvider({

View File

@ -16,7 +16,7 @@ import { RefreshTokenService } from 'src/engine/core-modules/auth/token/services
import { ExistingUserOrNewUser } from 'src/engine/core-modules/auth/types/signInUp.type';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EmailService } from 'src/engine/core-modules/email/email.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
import { UserService } from 'src/engine/core-modules/user/services/user.service';
import { User } from 'src/engine/core-modules/user/user.entity';
@ -35,7 +35,7 @@ const workspaceInvitationGetOneWorkspaceInvitationMock = jest.fn();
const workspaceInvitationValidatePersonalInvitationMock = jest.fn();
const userWorkspaceAddUserToWorkspaceMock = jest.fn();
const environmentServiceGetMock = jest.fn();
const twentyConfigServiceGetMock = jest.fn();
describe('AuthService', () => {
let service: AuthService;
@ -75,9 +75,9 @@ describe('AuthService', () => {
useValue: {},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: environmentServiceGetMock,
get: twentyConfigServiceGetMock,
},
},
{
@ -138,7 +138,7 @@ describe('AuthService', () => {
});
beforeEach(() => {
environmentServiceGetMock.mockReturnValue(false);
twentyConfigServiceGetMock.mockReturnValue(false);
});
it('should be defined', async () => {

View File

@ -13,7 +13,7 @@ import { APP_LOCALES } from 'twenty-shared/translations';
import { isDefined } from 'twenty-shared/utils';
import { Repository } from 'typeorm';
import { NodeEnvironment } from 'src/engine/core-modules/environment/interfaces/node-environment.interface';
import { NodeEnvironment } from 'src/engine/core-modules/twenty-config/interfaces/node-environment.interface';
import {
AppToken,
@ -51,7 +51,7 @@ import {
import { WorkspaceSubdomainCustomDomainAndIsCustomDomainEnabledType } from 'src/engine/core-modules/domain-manager/domain-manager.type';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EmailService } from 'src/engine/core-modules/email/email.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
import { UserService } from 'src/engine/core-modules/user/services/user.service';
import { User } from 'src/engine/core-modules/user/user.entity';
@ -77,7 +77,7 @@ export class AuthService {
private readonly workspaceRepository: Repository<Workspace>,
@InjectRepository(User, 'core')
private readonly userRepository: Repository<User>,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly emailService: EmailService,
@InjectRepository(AppToken, 'core')
private readonly appTokenRepository: Repository<AppToken>,
@ -164,7 +164,7 @@ export class AuthService {
);
}
const isEmailVerificationRequired = this.environmentService.get(
const isEmailVerificationRequired = this.twentyConfigService.get(
'IS_EMAIL_VERIFICATION_REQUIRED',
);
@ -323,10 +323,10 @@ export class AuthService {
id: 'chrome',
name: 'Chrome Extension',
redirectUrl:
this.environmentService.get('NODE_ENV') ===
this.twentyConfigService.get('NODE_ENV') ===
NodeEnvironment.development
? authorizeAppInput.redirectUrl
: `https://${this.environmentService.get(
: `https://${this.twentyConfigService.get(
'CHROME_EXTENSION_ID',
)}.chromiumapp.org/`,
},
@ -448,9 +448,9 @@ export class AuthService {
i18n.activate(locale);
this.emailService.send({
from: `${this.environmentService.get(
from: `${this.twentyConfigService.get(
'EMAIL_FROM_NAME',
)} <${this.environmentService.get('EMAIL_FROM_ADDRESS')}>`,
)} <${this.twentyConfigService.get('EMAIL_FROM_ADDRESS')}>`,
to: user.email,
subject: t`Your Password Has Been Successfully Changed`,
text,

View File

@ -1,16 +1,16 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { ConnectedAccountProvider } from 'twenty-shared/types';
import { EntityManager, Repository } from 'typeorm';
import { v4 } from 'uuid';
import { ConnectedAccountProvider } from 'twenty-shared/types';
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
import { getGoogleApisOauthScopes } from 'src/engine/core-modules/auth/utils/get-google-apis-oauth-scopes';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator';
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter';
@ -45,7 +45,7 @@ export class GoogleAPIsService {
private readonly messageQueueService: MessageQueueService,
@InjectMessageQueue(MessageQueue.calendarQueue)
private readonly calendarQueueService: MessageQueueService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly accountsToReconnectService: AccountsToReconnectService,
private readonly workspaceEventEmitter: WorkspaceEventEmitter,
@InjectRepository(ObjectMetadataEntity, 'metadata')
@ -69,7 +69,7 @@ export class GoogleAPIsService {
messageVisibility,
} = input;
const isCalendarEnabled = this.environmentService.get(
const isCalendarEnabled = this.twentyConfigService.get(
'CALENDAR_PROVIDER_GOOGLE_ENABLED',
);
@ -300,7 +300,7 @@ export class GoogleAPIsService {
}
});
if (this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED')) {
if (this.twentyConfigService.get('MESSAGING_PROVIDER_GMAIL_ENABLED')) {
const messageChannels = await messageChannelRepository.find({
where: {
connectedAccountId: newOrExistingConnectedAccountId,

View File

@ -1,16 +1,16 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { ConnectedAccountProvider } from 'twenty-shared/types';
import { EntityManager, Repository } from 'typeorm';
import { v4 } from 'uuid';
import { ConnectedAccountProvider } from 'twenty-shared/types';
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
import { getMicrosoftApisOauthScopes } from 'src/engine/core-modules/auth/utils/get-microsoft-apis-oauth-scopes';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator';
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter';
@ -51,7 +51,7 @@ export class MicrosoftAPIsService {
private readonly workspaceEventEmitter: WorkspaceEventEmitter,
@InjectRepository(ObjectMetadataEntity, 'metadata')
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {}
async refreshMicrosoftRefreshToken(input: {
@ -200,7 +200,7 @@ export class MicrosoftAPIsService {
});
if (
this.environmentService.get('CALENDAR_PROVIDER_MICROSOFT_ENABLED')
this.twentyConfigService.get('CALENDAR_PROVIDER_MICROSOFT_ENABLED')
) {
const newCalendarChannel = await calendarChannelRepository.save(
{
@ -328,7 +328,7 @@ export class MicrosoftAPIsService {
}
});
if (this.environmentService.get('MESSAGING_PROVIDER_MICROSOFT_ENABLED')) {
if (this.twentyConfigService.get('MESSAGING_PROVIDER_MICROSOFT_ENABLED')) {
const messageChannels = await messageChannelRepository.find({
where: {
connectedAccountId: newOrExistingConnectedAccountId,
@ -346,7 +346,7 @@ export class MicrosoftAPIsService {
}
}
if (this.environmentService.get('CALENDAR_PROVIDER_MICROSOFT_ENABLED')) {
if (this.twentyConfigService.get('CALENDAR_PROVIDER_MICROSOFT_ENABLED')) {
const calendarChannels = await calendarChannelRepository.find({
where: {
connectedAccountId: newOrExistingConnectedAccountId,

View File

@ -11,7 +11,7 @@ import {
import { AuthException } from 'src/engine/core-modules/auth/auth.exception';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EmailService } from 'src/engine/core-modules/email/email.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { User } from 'src/engine/core-modules/user/user.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@ -23,7 +23,7 @@ describe('ResetPasswordService', () => {
let workspaceRepository: Repository<Workspace>;
let appTokenRepository: Repository<AppToken>;
let emailService: EmailService;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
let domainManagerService: DomainManagerService;
beforeEach(async () => {
@ -62,7 +62,7 @@ describe('ResetPasswordService', () => {
},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -81,7 +81,7 @@ describe('ResetPasswordService', () => {
getRepositoryToken(AppToken, 'core'),
);
emailService = module.get<EmailService>(EmailService);
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
domainManagerService =
module.get<DomainManagerService>(DomainManagerService);
});
@ -99,7 +99,7 @@ describe('ResetPasswordService', () => {
.mockResolvedValue(mockUser as User);
jest.spyOn(appTokenRepository, 'findOne').mockResolvedValue(null);
jest.spyOn(appTokenRepository, 'save').mockResolvedValue({} as AppToken);
jest.spyOn(environmentService, 'get').mockReturnValue('1h');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('1h');
const result = await service.generatePasswordResetToken(
'test@example.com',
@ -165,7 +165,7 @@ describe('ResetPasswordService', () => {
.spyOn(workspaceRepository, 'findOneBy')
.mockResolvedValue({ id: 'workspace-id' } as Workspace);
jest
.spyOn(environmentService, 'get')
.spyOn(twentyConfigService, 'get')
.mockReturnValue('http://localhost:3000');
jest
.spyOn(domainManagerService, 'buildWorkspaceURL')

View File

@ -26,7 +26,7 @@ import { PasswordResetToken } from 'src/engine/core-modules/auth/dto/token.entit
import { ValidatePasswordResetToken } from 'src/engine/core-modules/auth/dto/validate-password-reset-token.entity';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EmailService } from 'src/engine/core-modules/email/email.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { User } from 'src/engine/core-modules/user/user.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
@ -34,7 +34,7 @@ import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.
@Injectable()
export class ResetPasswordService {
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly domainManagerService: DomainManagerService,
@InjectRepository(User, 'core')
private readonly userRepository: Repository<User>,
@ -60,7 +60,7 @@ export class ResetPasswordService {
);
}
const expiresIn = this.environmentService.get(
const expiresIn = this.twentyConfigService.get(
'PASSWORD_RESET_TOKEN_EXPIRES_IN',
);
@ -164,9 +164,9 @@ export class ResetPasswordService {
i18n.activate(locale);
this.emailService.send({
from: `${this.environmentService.get(
from: `${this.twentyConfigService.get(
'EMAIL_FROM_NAME',
)} <${this.environmentService.get('EMAIL_FROM_ADDRESS')}>`,
)} <${this.twentyConfigService.get('EMAIL_FROM_ADDRESS')}>`,
to: email,
subject: t`Action Needed to Reset Password`,
text,

View File

@ -2,8 +2,8 @@ import { HttpService } from '@nestjs/axios';
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
import { Repository } from 'typeorm';
import { AppToken } from 'src/engine/core-modules/app-token/app-token.entity';
import {
@ -17,10 +17,10 @@ import {
SignInUpBaseParams,
} from 'src/engine/core-modules/auth/types/signInUp.type';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service';
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
import { UserService } from 'src/engine/core-modules/user/services/user.service';
@ -42,7 +42,7 @@ describe('SignInUpService', () => {
let fileUploadService: FileUploadService;
let workspaceInvitationService: WorkspaceInvitationService;
let userWorkspaceService: UserWorkspaceService;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
let domainManagerService: DomainManagerService;
beforeEach(async () => {
@ -98,7 +98,7 @@ describe('SignInUpService', () => {
useValue: {},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -143,7 +143,7 @@ describe('SignInUpService', () => {
);
userWorkspaceService =
module.get<UserWorkspaceService>(UserWorkspaceService);
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
domainManagerService =
module.get<DomainManagerService>(DomainManagerService);
});
@ -242,7 +242,7 @@ describe('SignInUpService', () => {
},
};
jest.spyOn(environmentService, 'get').mockReturnValue(false);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(false);
jest.spyOn(WorkspaceRepository, 'count').mockResolvedValue(0);
jest.spyOn(WorkspaceRepository, 'create').mockReturnValue({} as Workspace);
jest.spyOn(WorkspaceRepository, 'save').mockResolvedValue({
@ -292,7 +292,7 @@ describe('SignInUpService', () => {
},
};
jest.spyOn(environmentService, 'get').mockReturnValue(false);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(false);
jest
.spyOn(userWorkspaceService, 'addUserToWorkspaceIfUserNotInWorkspace')
.mockResolvedValue(undefined);
@ -324,7 +324,7 @@ describe('SignInUpService', () => {
},
};
jest.spyOn(environmentService, 'get').mockReturnValue(false);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(false);
jest
.spyOn(userWorkspaceService, 'checkUserWorkspaceExists')
.mockResolvedValue(null);
@ -349,7 +349,7 @@ describe('SignInUpService', () => {
},
};
jest.spyOn(environmentService, 'get').mockReturnValue(false);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(false);
jest.spyOn(WorkspaceRepository, 'count').mockResolvedValue(0);
jest.spyOn(WorkspaceRepository, 'create').mockReturnValue({} as Workspace);
jest.spyOn(WorkspaceRepository, 'save').mockResolvedValue({

View File

@ -3,10 +3,10 @@ import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import FileType from 'file-type';
import { Repository } from 'typeorm';
import { v4 } from 'uuid';
import { TWENTY_ICONS_BASE_URL } from 'twenty-shared/constants';
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
import { Repository } from 'typeorm';
import { v4 } from 'uuid';
import { FileFolder } from 'src/engine/core-modules/file/interfaces/file-folder.interface';
@ -28,10 +28,10 @@ import {
SignInUpNewUserPayload,
} from 'src/engine/core-modules/auth/types/signInUp.type';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service';
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
import { UserService } from 'src/engine/core-modules/user/services/user.service';
import { User } from 'src/engine/core-modules/user/user.entity';
@ -55,7 +55,7 @@ export class SignInUpService {
private readonly userWorkspaceService: UserWorkspaceService,
private readonly onboardingService: OnboardingService,
private readonly httpService: HttpService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly domainManagerService: DomainManagerService,
private readonly userService: UserService,
private readonly userRoleService: UserRoleService,
@ -324,7 +324,7 @@ export class SignInUpService {
);
}
if (!this.environmentService.get('IS_MULTIWORKSPACE_ENABLED')) {
if (!this.twentyConfigService.get('IS_MULTIWORKSPACE_ENABLED')) {
const workspacesCount = await this.workspaceRepository.count();
// if the workspace doesn't exist it means it's the first user of the workspace

View File

@ -3,8 +3,8 @@ import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-google-oauth20';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { getGoogleApisOauthScopes } from 'src/engine/core-modules/auth/utils/get-google-apis-oauth-scopes';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
export type GoogleAPIScopeConfig = {
isCalendarEnabled?: boolean;
@ -16,13 +16,13 @@ export class GoogleAPIsOauthCommonStrategy extends PassportStrategy(
Strategy,
'google-apis',
) {
constructor(environmentService: EnvironmentService) {
constructor(twentyConfigService: TwentyConfigService) {
const scopes = getGoogleApisOauthScopes();
super({
clientID: environmentService.get('AUTH_GOOGLE_CLIENT_ID'),
clientSecret: environmentService.get('AUTH_GOOGLE_CLIENT_SECRET'),
callbackURL: environmentService.get('AUTH_GOOGLE_APIS_CALLBACK_URL'),
clientID: twentyConfigService.get('AUTH_GOOGLE_CLIENT_ID'),
clientSecret: twentyConfigService.get('AUTH_GOOGLE_CLIENT_SECRET'),
callbackURL: twentyConfigService.get('AUTH_GOOGLE_APIS_CALLBACK_URL'),
scope: scopes,
passReqToCallback: true,
});

View File

@ -4,7 +4,7 @@ import { VerifyCallback } from 'passport-google-oauth20';
import { GoogleAPIsOauthCommonStrategy } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-common.auth.strategy';
import { GoogleAPIsRequest } from 'src/engine/core-modules/auth/types/google-api-request.type';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
export type GoogleAPIScopeConfig = {
isCalendarEnabled?: boolean;
@ -12,8 +12,8 @@ export type GoogleAPIScopeConfig = {
@Injectable()
export class GoogleAPIsOauthExchangeCodeForTokenStrategy extends GoogleAPIsOauthCommonStrategy {
constructor(environmentService: EnvironmentService) {
super(environmentService);
constructor(twentyConfigService: TwentyConfigService) {
super(twentyConfigService);
}
async validate(

View File

@ -1,7 +1,7 @@
import { Injectable } from '@nestjs/common';
import { GoogleAPIsOauthCommonStrategy } from 'src/engine/core-modules/auth/strategies/google-apis-oauth-common.auth.strategy';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
export type GoogleAPIScopeConfig = {
isCalendarEnabled?: boolean;
@ -10,8 +10,8 @@ export type GoogleAPIScopeConfig = {
@Injectable()
export class GoogleAPIsOauthRequestCodeStrategy extends GoogleAPIsOauthCommonStrategy {
constructor(environmentService: EnvironmentService) {
super(environmentService);
constructor(twentyConfigService: TwentyConfigService) {
super(twentyConfigService);
}
authenticate(req: any, options: any) {

View File

@ -5,7 +5,7 @@ import { Request } from 'express';
import { Strategy, VerifyCallback } from 'passport-google-oauth20';
import { APP_LOCALES } from 'twenty-shared/translations';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
export type GoogleRequest = Omit<
Request,
@ -26,11 +26,11 @@ export type GoogleRequest = Omit<
@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
constructor(environmentService: EnvironmentService) {
constructor(twentyConfigService: TwentyConfigService) {
super({
clientID: environmentService.get('AUTH_GOOGLE_CLIENT_ID'),
clientSecret: environmentService.get('AUTH_GOOGLE_CLIENT_SECRET'),
callbackURL: environmentService.get('AUTH_GOOGLE_CALLBACK_URL'),
clientID: twentyConfigService.get('AUTH_GOOGLE_CLIENT_ID'),
clientSecret: twentyConfigService.get('AUTH_GOOGLE_CLIENT_SECRET'),
callbackURL: twentyConfigService.get('AUTH_GOOGLE_CALLBACK_URL'),
scope: ['email', 'profile'],
passReqToCallback: true,
});

View File

@ -14,8 +14,8 @@ import {
AuthContext,
JwtPayload,
} from 'src/engine/core-modules/auth/types/auth-context.type';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { User } from 'src/engine/core-modules/user/user.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@ -25,7 +25,7 @@ import { ApiKeyWorkspaceEntity } from 'src/modules/api-key/standard-objects/api-
@Injectable()
export class JwtAuthStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly jwtWrapperService: JwtWrapperService,
private readonly typeORMService: TypeORMService,
private readonly dataSourceService: DataSourceService,

View File

@ -4,7 +4,7 @@ import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-microsoft';
import { getMicrosoftApisOauthScopes } from 'src/engine/core-modules/auth/utils/get-microsoft-apis-oauth-scopes';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
export type MicrosoftAPIScopeConfig = {
isCalendarEnabled?: boolean;
@ -16,14 +16,14 @@ export class MicrosoftAPIsOauthCommonStrategy extends PassportStrategy(
Strategy,
'microsoft-apis',
) {
constructor(environmentService: EnvironmentService) {
constructor(twentyConfigService: TwentyConfigService) {
const scopes = getMicrosoftApisOauthScopes();
super({
clientID: environmentService.get('AUTH_MICROSOFT_CLIENT_ID'),
clientSecret: environmentService.get('AUTH_MICROSOFT_CLIENT_SECRET'),
clientID: twentyConfigService.get('AUTH_MICROSOFT_CLIENT_ID'),
clientSecret: twentyConfigService.get('AUTH_MICROSOFT_CLIENT_SECRET'),
tenant: 'common',
callbackURL: environmentService.get('AUTH_MICROSOFT_APIS_CALLBACK_URL'),
callbackURL: twentyConfigService.get('AUTH_MICROSOFT_APIS_CALLBACK_URL'),
scope: scopes,
passReqToCallback: true,
});

View File

@ -4,7 +4,7 @@ import { VerifyCallback } from 'passport-google-oauth20';
import { MicrosoftAPIsOauthCommonStrategy } from 'src/engine/core-modules/auth/strategies/microsoft-apis-oauth-common.auth.strategy';
import { MicrosoftAPIsRequest } from 'src/engine/core-modules/auth/types/microsoft-api-request.type';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
export type MicrosoftAPIScopeConfig = {
isCalendarEnabled?: boolean;
@ -12,8 +12,8 @@ export type MicrosoftAPIScopeConfig = {
@Injectable()
export class MicrosoftAPIsOauthExchangeCodeForTokenStrategy extends MicrosoftAPIsOauthCommonStrategy {
constructor(environmentService: EnvironmentService) {
super(environmentService);
constructor(twentyConfigService: TwentyConfigService) {
super(twentyConfigService);
}
async validate(

View File

@ -1,12 +1,12 @@
import { Injectable } from '@nestjs/common';
import { MicrosoftAPIsOauthCommonStrategy } from 'src/engine/core-modules/auth/strategies/microsoft-apis-oauth-common.auth.strategy';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class MicrosoftAPIsOauthRequestCodeStrategy extends MicrosoftAPIsOauthCommonStrategy {
constructor(environmentService: EnvironmentService) {
super(environmentService);
constructor(twentyConfigService: TwentyConfigService) {
super(twentyConfigService);
}
authenticate(req: any, options: any) {

View File

@ -9,7 +9,7 @@ import {
AuthException,
AuthExceptionCode,
} from 'src/engine/core-modules/auth/auth.exception';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
export type MicrosoftRequest = Omit<
Request,
@ -29,11 +29,11 @@ export type MicrosoftRequest = Omit<
};
export class MicrosoftStrategy extends PassportStrategy(Strategy, 'microsoft') {
constructor(environmentService: EnvironmentService) {
constructor(twentyConfigService: TwentyConfigService) {
super({
clientID: environmentService.get('AUTH_MICROSOFT_CLIENT_ID'),
clientSecret: environmentService.get('AUTH_MICROSOFT_CLIENT_SECRET'),
callbackURL: environmentService.get('AUTH_MICROSOFT_CALLBACK_URL'),
clientID: twentyConfigService.get('AUTH_MICROSOFT_CLIENT_ID'),
clientSecret: twentyConfigService.get('AUTH_MICROSOFT_CLIENT_SECRET'),
callbackURL: twentyConfigService.get('AUTH_MICROSOFT_CALLBACK_URL'),
tenant: 'common',
scope: ['user.read'],
passReqToCallback: true,

View File

@ -2,16 +2,16 @@ import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Request } from 'express';
import { Repository } from 'typeorm';
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
import { Repository } from 'typeorm';
import { AppToken } from 'src/engine/core-modules/app-token/app-token.entity';
import { AuthException } from 'src/engine/core-modules/auth/auth.exception';
import { JwtAuthStrategy } from 'src/engine/core-modules/auth/strategies/jwt.auth.strategy';
import { EmailService } from 'src/engine/core-modules/email/email.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { SSOService } from 'src/engine/core-modules/sso/services/sso.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { User } from 'src/engine/core-modules/user/user.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@ -22,7 +22,7 @@ import { AccessTokenService } from './access-token.service';
describe('AccessTokenService', () => {
let service: AccessTokenService;
let jwtWrapperService: JwtWrapperService;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
let userRepository: Repository<User>;
let workspaceRepository: Repository<Workspace>;
let twentyORMGlobalManager: TwentyORMGlobalManager;
@ -49,7 +49,7 @@ describe('AccessTokenService', () => {
},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -89,7 +89,7 @@ describe('AccessTokenService', () => {
service = module.get<AccessTokenService>(AccessTokenService);
jwtWrapperService = module.get<JwtWrapperService>(JwtWrapperService);
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
userRepository = module.get<Repository<User>>(
getRepositoryToken(User, 'core'),
);
@ -123,7 +123,7 @@ describe('AccessTokenService', () => {
const mockWorkspaceMember = { id: 'workspace-member-id' };
const mockToken = 'mock-token';
jest.spyOn(environmentService, 'get').mockReturnValue('1h');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('1h');
jest.spyOn(userRepository, 'findOne').mockResolvedValue(mockUser as User);
jest
.spyOn(workspaceRepository, 'findOne')
@ -155,7 +155,7 @@ describe('AccessTokenService', () => {
});
it('should throw an error if user is not found', async () => {
jest.spyOn(environmentService, 'get').mockReturnValue('1h');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('1h');
jest.spyOn(userRepository, 'findOne').mockResolvedValue(null);
await expect(

View File

@ -4,8 +4,8 @@ import { InjectRepository } from '@nestjs/typeorm';
import { addMilliseconds } from 'date-fns';
import { Request } from 'express';
import ms from 'ms';
import { Repository } from 'typeorm';
import { isWorkspaceActiveOrSuspended } from 'twenty-shared/workspace';
import { Repository } from 'typeorm';
import {
AuthException,
@ -17,8 +17,8 @@ import {
AuthContext,
JwtPayload,
} from 'src/engine/core-modules/auth/types/auth-context.type';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { User } from 'src/engine/core-modules/user/user.entity';
import { userValidator } from 'src/engine/core-modules/user/user.validate';
@ -32,7 +32,7 @@ export class AccessTokenService {
constructor(
private readonly jwtWrapperService: JwtWrapperService,
private readonly jwtStrategy: JwtAuthStrategy,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
@InjectRepository(User, 'core')
private readonly userRepository: Repository<User>,
@InjectRepository(Workspace, 'core')
@ -46,7 +46,7 @@ export class AccessTokenService {
userId: string,
workspaceId: string,
): Promise<AuthToken> {
const expiresIn = this.environmentService.get('ACCESS_TOKEN_EXPIRES_IN');
const expiresIn = this.twentyConfigService.get('ACCESS_TOKEN_EXPIRES_IN');
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));

View File

@ -13,14 +13,14 @@ import {
EmailVerificationException,
EmailVerificationExceptionCode,
} from 'src/engine/core-modules/email-verification/email-verification.exception';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { EmailVerificationTokenService } from './email-verification-token.service';
describe('EmailVerificationTokenService', () => {
let service: EmailVerificationTokenService;
let appTokenRepository: Repository<AppToken>;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
@ -31,7 +31,7 @@ describe('EmailVerificationTokenService', () => {
useClass: Repository,
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -45,7 +45,7 @@ describe('EmailVerificationTokenService', () => {
appTokenRepository = module.get<Repository<AppToken>>(
getRepositoryToken(AppToken, 'core'),
);
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
});
describe('generateToken', () => {
@ -54,7 +54,7 @@ describe('EmailVerificationTokenService', () => {
const email = 'test@example.com';
const mockExpiresIn = '24h';
jest.spyOn(environmentService, 'get').mockReturnValue(mockExpiresIn);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(mockExpiresIn);
jest.spyOn(appTokenRepository, 'create').mockReturnValue({} as AppToken);
jest.spyOn(appTokenRepository, 'save').mockResolvedValue({} as AppToken);

View File

@ -16,18 +16,18 @@ import {
EmailVerificationException,
EmailVerificationExceptionCode,
} from 'src/engine/core-modules/email-verification/email-verification.exception';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class EmailVerificationTokenService {
constructor(
@InjectRepository(AppToken, 'core')
private readonly appTokenRepository: Repository<AppToken>,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {}
async generateToken(userId: string, email: string): Promise<AuthToken> {
const expiresIn = this.environmentService.get(
const expiresIn = this.twentyConfigService.get(
'EMAIL_VERIFICATION_TOKEN_EXPIRES_IN',
);
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));

View File

@ -1,14 +1,14 @@
import { Test, TestingModule } from '@nestjs/testing';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { LoginTokenService } from './login-token.service';
describe('LoginTokenService', () => {
let service: LoginTokenService;
let jwtWrapperService: JwtWrapperService;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
@ -24,7 +24,7 @@ describe('LoginTokenService', () => {
},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -34,7 +34,7 @@ describe('LoginTokenService', () => {
service = module.get<LoginTokenService>(LoginTokenService);
jwtWrapperService = module.get<JwtWrapperService>(JwtWrapperService);
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
});
it('should be defined', () => {
@ -52,7 +52,7 @@ describe('LoginTokenService', () => {
jest
.spyOn(jwtWrapperService, 'generateAppSecret')
.mockReturnValue(mockSecret);
jest.spyOn(environmentService, 'get').mockReturnValue(mockExpiresIn);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(mockExpiresIn);
jest.spyOn(jwtWrapperService, 'sign').mockReturnValue(mockToken);
const result = await service.generateLoginToken(email, workspaceId);
@ -65,7 +65,7 @@ describe('LoginTokenService', () => {
'LOGIN',
workspaceId,
);
expect(environmentService.get).toHaveBeenCalledWith(
expect(twentyConfigService.get).toHaveBeenCalledWith(
'LOGIN_TOKEN_EXPIRES_IN',
);
expect(jwtWrapperService.sign).toHaveBeenCalledWith(

View File

@ -4,14 +4,14 @@ import { addMilliseconds } from 'date-fns';
import ms from 'ms';
import { AuthToken } from 'src/engine/core-modules/auth/dto/token.entity';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class LoginTokenService {
constructor(
private readonly jwtWrapperService: JwtWrapperService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {}
async generateLoginToken(
@ -23,7 +23,7 @@ export class LoginTokenService {
workspaceId,
);
const expiresIn = this.environmentService.get('LOGIN_TOKEN_EXPIRES_IN');
const expiresIn = this.twentyConfigService.get('LOGIN_TOKEN_EXPIRES_IN');
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
const jwtPayload = {

View File

@ -5,8 +5,8 @@ import { Repository } from 'typeorm';
import { AppToken } from 'src/engine/core-modules/app-token/app-token.entity';
import { AuthException } from 'src/engine/core-modules/auth/auth.exception';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { User } from 'src/engine/core-modules/user/user.entity';
import { RefreshTokenService } from './refresh-token.service';
@ -14,7 +14,7 @@ import { RefreshTokenService } from './refresh-token.service';
describe('RefreshTokenService', () => {
let service: RefreshTokenService;
let jwtWrapperService: JwtWrapperService;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
let appTokenRepository: Repository<AppToken>;
let userRepository: Repository<User>;
@ -32,7 +32,7 @@ describe('RefreshTokenService', () => {
},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -50,7 +50,7 @@ describe('RefreshTokenService', () => {
service = module.get<RefreshTokenService>(RefreshTokenService);
jwtWrapperService = module.get<JwtWrapperService>(JwtWrapperService);
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
appTokenRepository = module.get<Repository<AppToken>>(
getRepositoryToken(AppToken, 'core'),
);
@ -91,7 +91,7 @@ describe('RefreshTokenService', () => {
.spyOn(appTokenRepository, 'findOneBy')
.mockResolvedValue(mockAppToken as AppToken);
jest.spyOn(userRepository, 'findOne').mockResolvedValue(mockUser as User);
jest.spyOn(environmentService, 'get').mockReturnValue('1h');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('1h');
const result = await service.verifyRefreshToken(mockToken);
@ -123,7 +123,7 @@ describe('RefreshTokenService', () => {
const mockToken = 'mock-refresh-token';
const mockExpiresIn = '7d';
jest.spyOn(environmentService, 'get').mockReturnValue(mockExpiresIn);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(mockExpiresIn);
jest
.spyOn(jwtWrapperService, 'generateAppSecret')
.mockReturnValue('mock-secret');
@ -153,7 +153,7 @@ describe('RefreshTokenService', () => {
});
it('should throw an error if expiration time is not set', async () => {
jest.spyOn(environmentService, 'get').mockReturnValue(undefined);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(undefined);
await expect(
service.generateRefreshToken('user-id', 'workspace-id'),

View File

@ -14,15 +14,15 @@ import {
AuthExceptionCode,
} from 'src/engine/core-modules/auth/auth.exception';
import { AuthToken } from 'src/engine/core-modules/auth/dto/token.entity';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { User } from 'src/engine/core-modules/user/user.entity';
@Injectable()
export class RefreshTokenService {
constructor(
private readonly jwtWrapperService: JwtWrapperService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
@InjectRepository(AppToken, 'core')
private readonly appTokenRepository: Repository<AppToken>,
@InjectRepository(User, 'core')
@ -30,7 +30,7 @@ export class RefreshTokenService {
) {}
async verifyRefreshToken(refreshToken: string) {
const coolDown = this.environmentService.get('REFRESH_TOKEN_COOL_DOWN');
const coolDown = this.twentyConfigService.get('REFRESH_TOKEN_COOL_DOWN');
await this.jwtWrapperService.verifyWorkspaceToken(refreshToken, 'REFRESH');
const jwtPayload = await this.jwtWrapperService.decode(refreshToken);
@ -109,7 +109,7 @@ export class RefreshTokenService {
'REFRESH',
workspaceId,
);
const expiresIn = this.environmentService.get('REFRESH_TOKEN_EXPIRES_IN');
const expiresIn = this.twentyConfigService.get('REFRESH_TOKEN_EXPIRES_IN');
if (!expiresIn) {
throw new AuthException(

View File

@ -1,14 +1,14 @@
import { Test, TestingModule } from '@nestjs/testing';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { TransientTokenService } from './transient-token.service';
describe('TransientTokenService', () => {
let service: TransientTokenService;
let jwtWrapperService: JwtWrapperService;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
@ -24,7 +24,7 @@ describe('TransientTokenService', () => {
},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -34,7 +34,7 @@ describe('TransientTokenService', () => {
service = module.get<TransientTokenService>(TransientTokenService);
jwtWrapperService = module.get<JwtWrapperService>(JwtWrapperService);
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
});
it('should be defined', () => {
@ -49,7 +49,7 @@ describe('TransientTokenService', () => {
const mockExpiresIn = '15m';
const mockToken = 'mock-token';
jest.spyOn(environmentService, 'get').mockImplementation((key) => {
jest.spyOn(twentyConfigService, 'get').mockImplementation((key) => {
if (key === 'SHORT_TERM_TOKEN_EXPIRES_IN') return mockExpiresIn;
return undefined;
@ -66,7 +66,7 @@ describe('TransientTokenService', () => {
token: mockToken,
expiresAt: expect.any(Date),
});
expect(environmentService.get).toHaveBeenCalledWith(
expect(twentyConfigService.get).toHaveBeenCalledWith(
'SHORT_TERM_TOKEN_EXPIRES_IN',
);
expect(jwtWrapperService.sign).toHaveBeenCalledWith(

View File

@ -4,14 +4,14 @@ import { addMilliseconds } from 'date-fns';
import ms from 'ms';
import { AuthToken } from 'src/engine/core-modules/auth/dto/token.entity';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class TransientTokenService {
constructor(
private readonly jwtWrapperService: JwtWrapperService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {}
async generateTransientToken(
@ -23,7 +23,7 @@ export class TransientTokenService {
'LOGIN',
workspaceId,
);
const expiresIn = this.environmentService.get(
const expiresIn = this.twentyConfigService.get(
'SHORT_TERM_TOKEN_EXPIRES_IN',
);

View File

@ -6,21 +6,21 @@ import { OnCustomBatchEvent } from 'src/engine/api/graphql/graphql-query-runner/
import { BILLING_FEATURE_USED } from 'src/engine/core-modules/billing/constants/billing-feature-used.constant';
import { BillingUsageService } from 'src/engine/core-modules/billing/services/billing-usage.service';
import { BillingUsageEvent } from 'src/engine/core-modules/billing/types/billing-usage-event.type';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event.type';
@Injectable()
export class BillingFeatureUsedListener {
constructor(
private readonly billingUsageService: BillingUsageService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {}
@OnCustomBatchEvent(BILLING_FEATURE_USED)
async handleBillingFeatureUsedEvent(
payload: WorkspaceEventBatch<BillingUsageEvent>,
) {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return;
}

View File

@ -8,11 +8,11 @@ import {
UpdateSubscriptionQuantityJob,
UpdateSubscriptionQuantityJobData,
} from 'src/engine/core-modules/billing/jobs/update-subscription-quantity.job';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { ObjectRecordCreateEvent } from 'src/engine/core-modules/event-emitter/types/object-record-create.event';
import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator';
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event.type';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
@ -21,7 +21,7 @@ export class BillingWorkspaceMemberListener {
constructor(
@InjectMessageQueue(MessageQueue.billingQueue)
private readonly messageQueueService: MessageQueueService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {}
@OnDatabaseBatchEvent('workspaceMember', DatabaseEventAction.CREATED)
@ -31,7 +31,7 @@ export class BillingWorkspaceMemberListener {
ObjectRecordCreateEvent<WorkspaceMemberWorkspaceEntity>
>,
) {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return;
}

View File

@ -17,7 +17,7 @@ import { BillingSubscriptionItemService } from 'src/engine/core-modules/billing/
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
import { StripeBillingMeterEventService } from 'src/engine/core-modules/billing/stripe/services/stripe-billing-meter-event.service';
import { BillingUsageEvent } from 'src/engine/core-modules/billing/types/billing-usage-event.type';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Injectable()
@ -28,12 +28,12 @@ export class BillingUsageService {
private readonly billingCustomerRepository: Repository<BillingCustomer>,
private readonly billingSubscriptionService: BillingSubscriptionService,
private readonly stripeBillingMeterEventService: StripeBillingMeterEventService,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly billingSubscriptionItemService: BillingSubscriptionItemService,
) {}
async canFeatureBeUsed(workspaceId: string): Promise<boolean> {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return true;
}

View File

@ -13,15 +13,15 @@ import { SubscriptionStatus } from 'src/engine/core-modules/billing/enums/billin
import { BillingProductService } from 'src/engine/core-modules/billing/services/billing-product.service';
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
import { getPlanKeyFromSubscription } from 'src/engine/core-modules/billing/utils/get-plan-key-from-subscription.util';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class BillingService {
protected readonly logger = new Logger(BillingService.name);
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly billingSubscriptionService: BillingSubscriptionService,
private readonly billingProductService: BillingProductService,
private readonly featureFlagService: FeatureFlagService,
@ -30,7 +30,7 @@ export class BillingService {
) {}
isBillingEnabled() {
return this.environmentService.get('IS_BILLING_ENABLED');
return this.twentyConfigService.get('IS_BILLING_ENABLED');
}
async hasWorkspaceAnySubscription(workspaceId: string) {

View File

@ -6,7 +6,7 @@ import Stripe from 'stripe';
import { BillingMeterEventName } from 'src/engine/core-modules/billing/enums/billing-meter-event-names';
import { StripeSDKService } from 'src/engine/core-modules/billing/stripe/stripe-sdk/services/stripe-sdk.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class StripeBillingMeterEventService {
@ -14,14 +14,14 @@ export class StripeBillingMeterEventService {
private readonly stripe: Stripe;
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly stripeSDKService: StripeSDKService,
) {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return;
}
this.stripe = this.stripeSDKService.getStripe(
this.environmentService.get('BILLING_STRIPE_API_KEY'),
this.twentyConfigService.get('BILLING_STRIPE_API_KEY'),
);
}

View File

@ -5,7 +5,7 @@ import { Injectable, Logger } from '@nestjs/common';
import Stripe from 'stripe';
import { StripeSDKService } from 'src/engine/core-modules/billing/stripe/stripe-sdk/services/stripe-sdk.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class StripeBillingMeterService {
@ -13,14 +13,14 @@ export class StripeBillingMeterService {
private readonly stripe: Stripe;
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly stripeSDKService: StripeSDKService,
) {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return;
}
this.stripe = this.stripeSDKService.getStripe(
this.environmentService.get('BILLING_STRIPE_API_KEY'),
this.twentyConfigService.get('BILLING_STRIPE_API_KEY'),
);
}

View File

@ -6,7 +6,7 @@ import Stripe from 'stripe';
import { StripeSDKService } from 'src/engine/core-modules/billing/stripe/stripe-sdk/services/stripe-sdk.service';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class StripeBillingPortalService {
@ -14,15 +14,15 @@ export class StripeBillingPortalService {
private readonly stripe: Stripe;
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly domainManagerService: DomainManagerService,
private readonly stripeSDKService: StripeSDKService,
) {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return;
}
this.stripe = this.stripeSDKService.getStripe(
this.environmentService.get('BILLING_STRIPE_API_KEY'),
this.twentyConfigService.get('BILLING_STRIPE_API_KEY'),
);
}

View File

@ -6,7 +6,7 @@ import Stripe from 'stripe';
import { BillingPlanKey } from 'src/engine/core-modules/billing/enums/billing-plan-key.enum';
import { StripeSDKService } from 'src/engine/core-modules/billing/stripe/stripe-sdk/services/stripe-sdk.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { User } from 'src/engine/core-modules/user/user.entity';
@Injectable()
@ -15,14 +15,14 @@ export class StripeCheckoutService {
private readonly stripe: Stripe;
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly stripeSDKService: StripeSDKService,
) {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return;
}
this.stripe = this.stripeSDKService.getStripe(
this.environmentService.get('BILLING_STRIPE_API_KEY'),
this.twentyConfigService.get('BILLING_STRIPE_API_KEY'),
);
}
@ -57,7 +57,7 @@ export class StripeCheckoutService {
},
...(withTrialPeriod
? {
trial_period_days: this.environmentService.get(
trial_period_days: this.twentyConfigService.get(
requirePaymentMethod
? 'BILLING_FREE_TRIAL_WITH_CREDIT_CARD_DURATION_IN_DAYS'
: 'BILLING_FREE_TRIAL_WITHOUT_CREDIT_CARD_DURATION_IN_DAYS',

View File

@ -5,7 +5,7 @@ import { Injectable, Logger } from '@nestjs/common';
import Stripe from 'stripe';
import { StripeSDKService } from 'src/engine/core-modules/billing/stripe/stripe-sdk/services/stripe-sdk.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class StripeCustomerService {
@ -13,14 +13,14 @@ export class StripeCustomerService {
private readonly stripe: Stripe;
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly stripeSDKService: StripeSDKService,
) {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return;
}
this.stripe = this.stripeSDKService.getStripe(
this.environmentService.get('BILLING_STRIPE_API_KEY'),
this.twentyConfigService.get('BILLING_STRIPE_API_KEY'),
);
}

View File

@ -5,7 +5,7 @@ import { Injectable, Logger } from '@nestjs/common';
import Stripe from 'stripe';
import { StripeSDKService } from 'src/engine/core-modules/billing/stripe/stripe-sdk/services/stripe-sdk.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class StripePriceService {
@ -13,14 +13,14 @@ export class StripePriceService {
private readonly stripe: Stripe;
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly stripeSDKService: StripeSDKService,
) {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return;
}
this.stripe = this.stripeSDKService.getStripe(
this.environmentService.get('BILLING_STRIPE_API_KEY'),
this.twentyConfigService.get('BILLING_STRIPE_API_KEY'),
);
}

View File

@ -5,7 +5,7 @@ import { Injectable, Logger } from '@nestjs/common';
import Stripe from 'stripe';
import { StripeSDKService } from 'src/engine/core-modules/billing/stripe/stripe-sdk/services/stripe-sdk.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class StripeProductService {
@ -13,14 +13,14 @@ export class StripeProductService {
private readonly stripe: Stripe;
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly stripeSDKService: StripeSDKService,
) {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return;
}
this.stripe = this.stripeSDKService.getStripe(
this.environmentService.get('BILLING_STRIPE_API_KEY'),
this.twentyConfigService.get('BILLING_STRIPE_API_KEY'),
);
}

View File

@ -5,7 +5,7 @@ import { Injectable, Logger } from '@nestjs/common';
import Stripe from 'stripe';
import { StripeSDKService } from 'src/engine/core-modules/billing/stripe/stripe-sdk/services/stripe-sdk.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class StripeSubscriptionItemService {
@ -13,14 +13,14 @@ export class StripeSubscriptionItemService {
private readonly stripe: Stripe;
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly stripeSDKService: StripeSDKService,
) {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return;
}
this.stripe = this.stripeSDKService.getStripe(
this.environmentService.get('BILLING_STRIPE_API_KEY'),
this.twentyConfigService.get('BILLING_STRIPE_API_KEY'),
);
}

View File

@ -6,7 +6,7 @@ import Stripe from 'stripe';
import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity';
import { StripeSDKService } from 'src/engine/core-modules/billing/stripe/stripe-sdk/services/stripe-sdk.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class StripeSubscriptionService {
@ -14,14 +14,14 @@ export class StripeSubscriptionService {
private readonly stripe: Stripe;
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly stripeSDKService: StripeSDKService,
) {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return;
}
this.stripe = this.stripeSDKService.getStripe(
this.environmentService.get('BILLING_STRIPE_API_KEY'),
this.twentyConfigService.get('BILLING_STRIPE_API_KEY'),
);
}

View File

@ -5,26 +5,26 @@ import { Injectable, Logger } from '@nestjs/common';
import Stripe from 'stripe';
import { StripeSDKService } from 'src/engine/core-modules/billing/stripe/stripe-sdk/services/stripe-sdk.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class StripeWebhookService {
protected readonly logger = new Logger(StripeWebhookService.name);
private stripe: Stripe;
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly stripeSDKService: StripeSDKService,
) {
if (!this.environmentService.get('IS_BILLING_ENABLED')) {
if (!this.twentyConfigService.get('IS_BILLING_ENABLED')) {
return;
}
this.stripe = this.stripeSDKService.getStripe(
this.environmentService.get('BILLING_STRIPE_API_KEY'),
this.twentyConfigService.get('BILLING_STRIPE_API_KEY'),
);
}
constructEventFromPayload(signature: string, payload: Buffer) {
const webhookSecret = this.environmentService.get(
const webhookSecret = this.twentyConfigService.get(
'BILLING_STRIPE_WEBHOOK_SECRET',
);

View File

@ -3,13 +3,13 @@ import { CacheModuleOptions } from '@nestjs/common';
import { redisStore } from 'cache-manager-redis-yet';
import { CacheStorageType } from 'src/engine/core-modules/cache-storage/types/cache-storage-type.enum';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
export const cacheStorageModuleFactory = (
environmentService: EnvironmentService,
twentyConfigService: TwentyConfigService,
): CacheModuleOptions => {
const cacheStorageType = CacheStorageType.Redis;
const cacheStorageTtl = environmentService.get('CACHE_STORAGE_TTL');
const cacheStorageTtl = twentyConfigService.get('CACHE_STORAGE_TTL');
const cacheModuleOptions: CacheModuleOptions = {
isGlobal: true,
ttl: cacheStorageTtl * 1000,
@ -20,7 +20,7 @@ export const cacheStorageModuleFactory = (
return cacheModuleOptions;
}*/
case CacheStorageType.Redis: {
const redisUrl = environmentService.get('REDIS_URL');
const redisUrl = twentyConfigService.get('REDIS_URL');
if (!redisUrl) {
throw new Error(

View File

@ -6,7 +6,7 @@ import { cacheStorageModuleFactory } from 'src/engine/core-modules/cache-storage
import { FlushCacheCommand } from 'src/engine/core-modules/cache-storage/commands/flush-cache.command';
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Global()
@Module({
@ -15,7 +15,7 @@ import { EnvironmentService } from 'src/engine/core-modules/environment/environm
isGlobal: true,
imports: [ConfigModule],
useFactory: cacheStorageModuleFactory,
inject: [EnvironmentService],
inject: [TwentyConfigService],
}),
],
providers: [

View File

@ -2,14 +2,14 @@ import {
CaptchaDriverOptions,
CaptchaModuleOptions,
} from 'src/engine/core-modules/captcha/interfaces';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
export const captchaModuleFactory = (
environmentService: EnvironmentService,
twentyConfigService: TwentyConfigService,
): CaptchaModuleOptions | undefined => {
const driver = environmentService.get('CAPTCHA_DRIVER');
const siteKey = environmentService.get('CAPTCHA_SITE_KEY');
const secretKey = environmentService.get('CAPTCHA_SECRET_KEY');
const driver = twentyConfigService.get('CAPTCHA_DRIVER');
const siteKey = twentyConfigService.get('CAPTCHA_SITE_KEY');
const secretKey = twentyConfigService.get('CAPTCHA_SECRET_KEY');
if (!driver) {
return;

View File

@ -1,7 +1,7 @@
import { Test, TestingModule } from '@nestjs/testing';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { ClientConfigResolver } from './client-config.resolver';
@ -13,7 +13,7 @@ describe('ClientConfigResolver', () => {
providers: [
ClientConfigResolver,
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {},
},
{

View File

@ -1,17 +1,17 @@
import { Query, Resolver } from '@nestjs/graphql';
import { NodeEnvironment } from 'src/engine/core-modules/environment/interfaces/node-environment.interface';
import { NodeEnvironment } from 'src/engine/core-modules/twenty-config/interfaces/node-environment.interface';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { PUBLIC_FEATURE_FLAGS } from 'src/engine/core-modules/feature-flag/constants/public-feature-flag.const';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { ClientConfig } from './client-config.entity';
@Resolver()
export class ClientConfigResolver {
constructor(
private environmentService: EnvironmentService,
private twentyConfigService: TwentyConfigService,
private domainManagerService: DomainManagerService,
) {}
@ -19,17 +19,17 @@ export class ClientConfigResolver {
async clientConfig(): Promise<ClientConfig> {
const clientConfig: ClientConfig = {
billing: {
isBillingEnabled: this.environmentService.get('IS_BILLING_ENABLED'),
billingUrl: this.environmentService.get('BILLING_PLAN_REQUIRED_LINK'),
isBillingEnabled: this.twentyConfigService.get('IS_BILLING_ENABLED'),
billingUrl: this.twentyConfigService.get('BILLING_PLAN_REQUIRED_LINK'),
trialPeriods: [
{
duration: this.environmentService.get(
duration: this.twentyConfigService.get(
'BILLING_FREE_TRIAL_WITH_CREDIT_CARD_DURATION_IN_DAYS',
),
isCreditCardRequired: true,
},
{
duration: this.environmentService.get(
duration: this.twentyConfigService.get(
'BILLING_FREE_TRIAL_WITHOUT_CREDIT_CARD_DURATION_IN_DAYS',
),
isCreditCardRequired: false,
@ -37,63 +37,64 @@ export class ClientConfigResolver {
],
},
authProviders: {
google: this.environmentService.get('AUTH_GOOGLE_ENABLED'),
google: this.twentyConfigService.get('AUTH_GOOGLE_ENABLED'),
magicLink: false,
password: this.environmentService.get('AUTH_PASSWORD_ENABLED'),
microsoft: this.environmentService.get('AUTH_MICROSOFT_ENABLED'),
password: this.twentyConfigService.get('AUTH_PASSWORD_ENABLED'),
microsoft: this.twentyConfigService.get('AUTH_MICROSOFT_ENABLED'),
sso: [],
},
signInPrefilled: this.environmentService.get('SIGN_IN_PREFILLED'),
isMultiWorkspaceEnabled: this.environmentService.get(
signInPrefilled: this.twentyConfigService.get('SIGN_IN_PREFILLED'),
isMultiWorkspaceEnabled: this.twentyConfigService.get(
'IS_MULTIWORKSPACE_ENABLED',
),
isEmailVerificationRequired: this.environmentService.get(
isEmailVerificationRequired: this.twentyConfigService.get(
'IS_EMAIL_VERIFICATION_REQUIRED',
),
defaultSubdomain: this.environmentService.get('DEFAULT_SUBDOMAIN'),
defaultSubdomain: this.twentyConfigService.get('DEFAULT_SUBDOMAIN'),
frontDomain: this.domainManagerService.getFrontUrl().hostname,
debugMode:
this.environmentService.get('NODE_ENV') === NodeEnvironment.development,
this.twentyConfigService.get('NODE_ENV') ===
NodeEnvironment.development,
support: {
supportDriver: this.environmentService.get('SUPPORT_DRIVER'),
supportFrontChatId: this.environmentService.get(
supportDriver: this.twentyConfigService.get('SUPPORT_DRIVER'),
supportFrontChatId: this.twentyConfigService.get(
'SUPPORT_FRONT_CHAT_ID',
),
},
sentry: {
environment: this.environmentService.get('SENTRY_ENVIRONMENT'),
release: this.environmentService.get('SENTRY_RELEASE'),
dsn: this.environmentService.get('SENTRY_FRONT_DSN'),
environment: this.twentyConfigService.get('SENTRY_ENVIRONMENT'),
release: this.twentyConfigService.get('SENTRY_RELEASE'),
dsn: this.twentyConfigService.get('SENTRY_FRONT_DSN'),
},
captcha: {
provider: this.environmentService.get('CAPTCHA_DRIVER'),
siteKey: this.environmentService.get('CAPTCHA_SITE_KEY'),
provider: this.twentyConfigService.get('CAPTCHA_DRIVER'),
siteKey: this.twentyConfigService.get('CAPTCHA_SITE_KEY'),
},
chromeExtensionId: this.environmentService.get('CHROME_EXTENSION_ID'),
chromeExtensionId: this.twentyConfigService.get('CHROME_EXTENSION_ID'),
api: {
mutationMaximumAffectedRecords: this.environmentService.get(
mutationMaximumAffectedRecords: this.twentyConfigService.get(
'MUTATION_MAXIMUM_AFFECTED_RECORDS',
),
},
isAttachmentPreviewEnabled: this.environmentService.get(
isAttachmentPreviewEnabled: this.twentyConfigService.get(
'IS_ATTACHMENT_PREVIEW_ENABLED',
),
analyticsEnabled: this.environmentService.get('ANALYTICS_ENABLED'),
analyticsEnabled: this.twentyConfigService.get('ANALYTICS_ENABLED'),
canManageFeatureFlags:
this.environmentService.get('NODE_ENV') ===
this.twentyConfigService.get('NODE_ENV') ===
NodeEnvironment.development ||
this.environmentService.get('IS_BILLING_ENABLED'),
this.twentyConfigService.get('IS_BILLING_ENABLED'),
publicFeatureFlags: PUBLIC_FEATURE_FLAGS,
isMicrosoftMessagingEnabled: this.environmentService.get(
isMicrosoftMessagingEnabled: this.twentyConfigService.get(
'MESSAGING_PROVIDER_MICROSOFT_ENABLED',
),
isMicrosoftCalendarEnabled: this.environmentService.get(
isMicrosoftCalendarEnabled: this.twentyConfigService.get(
'CALENDAR_PROVIDER_MICROSOFT_ENABLED',
),
isGoogleMessagingEnabled: this.environmentService.get(
isGoogleMessagingEnabled: this.twentyConfigService.get(
'MESSAGING_PROVIDER_GMAIL_ENABLED',
),
isGoogleCalendarEnabled: this.environmentService.get(
isGoogleCalendarEnabled: this.twentyConfigService.get(
'CALENDAR_PROVIDER_GOOGLE_ENABLED',
),
};

View File

@ -14,8 +14,6 @@ import { CaptchaModule } from 'src/engine/core-modules/captcha/captcha.module';
import { captchaModuleFactory } from 'src/engine/core-modules/captcha/captcha.module-factory';
import { EmailModule } from 'src/engine/core-modules/email/email.module';
import { emailModuleFactory } from 'src/engine/core-modules/email/email.module-factory';
import { EnvironmentModule } from 'src/engine/core-modules/environment/environment.module';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { ExceptionHandlerModule } from 'src/engine/core-modules/exception-handler/exception-handler.module';
import { exceptionHandlerModuleFactory } from 'src/engine/core-modules/exception-handler/exception-handler.module-factory';
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
@ -42,6 +40,8 @@ import { serverlessModuleFactory } from 'src/engine/core-modules/serverless/serv
import { ServerlessModule } from 'src/engine/core-modules/serverless/serverless.module';
import { WorkspaceSSOModule } from 'src/engine/core-modules/sso/sso.module';
import { TelemetryModule } from 'src/engine/core-modules/telemetry/telemetry.module';
import { TwentyConfigModule } from 'src/engine/core-modules/twenty-config/twenty-config.module';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { UserModule } from 'src/engine/core-modules/user/user.module';
import { WorkflowApiModule } from 'src/engine/core-modules/workflow/workflow-api.module';
import { WorkspaceInvitationModule } from 'src/engine/core-modules/workspace-invitation/workspace-invitation.module';
@ -79,31 +79,31 @@ import { FileModule } from './file/file.module';
AdminPanelModule,
LabModule,
RoleModule,
EnvironmentModule.forRoot({}),
TwentyConfigModule,
RedisClientModule,
FileStorageModule.forRootAsync({
useFactory: fileStorageModuleFactory,
inject: [EnvironmentService],
inject: [TwentyConfigService],
}),
LoggerModule.forRootAsync({
useFactory: loggerModuleFactory,
inject: [EnvironmentService],
inject: [TwentyConfigService],
}),
MessageQueueModule.registerAsync({
useFactory: messageQueueModuleFactory,
inject: [EnvironmentService, RedisClientService],
inject: [TwentyConfigService, RedisClientService],
}),
ExceptionHandlerModule.forRootAsync({
useFactory: exceptionHandlerModuleFactory,
inject: [EnvironmentService, HttpAdapterHost],
inject: [TwentyConfigService, HttpAdapterHost],
}),
EmailModule.forRoot({
useFactory: emailModuleFactory,
inject: [EnvironmentService],
inject: [TwentyConfigService],
}),
CaptchaModule.forRoot({
useFactory: captchaModuleFactory,
inject: [EnvironmentService],
inject: [TwentyConfigService],
}),
EventEmitterModule.forRoot({
wildcard: true,
@ -111,15 +111,15 @@ import { FileModule } from './file/file.module';
CacheStorageModule,
LLMChatModelModule.forRoot({
useFactory: llmChatModelModuleFactory,
inject: [EnvironmentService],
inject: [TwentyConfigService],
}),
LLMTracingModule.forRoot({
useFactory: llmTracingModuleFactory,
inject: [EnvironmentService],
inject: [TwentyConfigService],
}),
ServerlessModule.forRootAsync({
useFactory: serverlessModuleFactory,
inject: [EnvironmentService, FileStorageService],
inject: [TwentyConfigService, FileStorageService],
}),
SearchModule,
],

View File

@ -1,22 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Request, Response } from 'express';
import { Repository } from 'typeorm';
import { CloudflareController } from 'src/engine/core-modules/domain-manager/controllers/cloudflare.controller';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { HttpExceptionHandlerService } from 'src/engine/core-modules/exception-handler/http-exception-handler.service';
import { CustomDomainValidRecords } from 'src/engine/core-modules/domain-manager/dtos/custom-domain-valid-records';
import { CustomDomainService } from 'src/engine/core-modules/domain-manager/services/custom-domain.service';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
import { HttpExceptionHandlerService } from 'src/engine/core-modules/exception-handler/http-exception-handler.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
describe('CloudflareController - customHostnameWebhooks', () => {
let controller: CloudflareController;
let WorkspaceRepository: Repository<Workspace>;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
let domainManagerService: DomainManagerService;
let customDomainService: CustomDomainService;
@ -56,7 +56,7 @@ describe('CloudflareController - customHostnameWebhooks', () => {
},
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -66,7 +66,7 @@ describe('CloudflareController - customHostnameWebhooks', () => {
controller = module.get<CloudflareController>(CloudflareController);
WorkspaceRepository = module.get(getRepositoryToken(Workspace, 'core'));
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
domainManagerService =
module.get<DomainManagerService>(DomainManagerService);
customDomainService = module.get<CustomDomainService>(CustomDomainService);
@ -83,7 +83,7 @@ describe('CloudflareController - customHostnameWebhooks', () => {
send: sendMock,
} as unknown as Response;
jest.spyOn(environmentService, 'get').mockReturnValue('correct-secret');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('correct-secret');
await controller.customHostnameWebhooks(req, res);
@ -102,7 +102,7 @@ describe('CloudflareController - customHostnameWebhooks', () => {
send: sendMock,
} as unknown as Response;
jest.spyOn(environmentService, 'get').mockReturnValue('correct-secret');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('correct-secret');
jest
.spyOn(customDomainService, 'getCustomDomainDetails')
.mockResolvedValue({
@ -147,7 +147,7 @@ describe('CloudflareController - customHostnameWebhooks', () => {
send: sendMock,
} as unknown as Response;
jest.spyOn(environmentService, 'get').mockReturnValue('correct-secret');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('correct-secret');
jest.spyOn(WorkspaceRepository, 'findOneBy').mockResolvedValue({
customDomain: 'notfound.com',
isCustomDomainEnabled: true,
@ -180,7 +180,7 @@ describe('CloudflareController - customHostnameWebhooks', () => {
send: sendMock,
} as unknown as Response;
jest.spyOn(environmentService, 'get').mockReturnValue('correct-secret');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('correct-secret');
jest.spyOn(WorkspaceRepository, 'findOneBy').mockResolvedValue({
customDomain: 'nothing-change.com',
isCustomDomainEnabled: true,

View File

@ -4,17 +4,17 @@ import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { timingSafeEqual } from 'crypto';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class CloudflareSecretMatchGuard implements CanActivate {
constructor(private readonly environmentService: EnvironmentService) {}
constructor(private readonly twentyConfigService: TwentyConfigService) {}
canActivate(context: ExecutionContext): boolean {
try {
const request = context.switchToHttp().getRequest<Request>();
const cloudflareWebhookSecret = this.environmentService.get(
const cloudflareWebhookSecret = this.twentyConfigService.get(
'CLOUDFLARE_WEBHOOK_SECRET',
);

View File

@ -2,25 +2,25 @@ import { ExecutionContext } from '@nestjs/common';
import * as crypto from 'crypto';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { CloudflareSecretMatchGuard } from './cloudflare-secret.guard';
describe('CloudflareSecretMatchGuard.canActivate', () => {
let guard: CloudflareSecretMatchGuard;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
beforeEach(() => {
environmentService = {
twentyConfigService = {
get: jest.fn(),
} as unknown as EnvironmentService;
guard = new CloudflareSecretMatchGuard(environmentService);
} as unknown as TwentyConfigService;
guard = new CloudflareSecretMatchGuard(twentyConfigService);
});
it('should return true when the webhook secret matches', () => {
const mockRequest = { headers: { 'cf-webhook-auth': 'valid-secret' } };
jest.spyOn(environmentService, 'get').mockReturnValue('valid-secret');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('valid-secret');
const mockContext = {
switchToHttp: () => ({
@ -36,7 +36,7 @@ describe('CloudflareSecretMatchGuard.canActivate', () => {
it('should return true when env is not set', () => {
const mockRequest = { headers: { 'cf-webhook-auth': 'valid-secret' } };
jest.spyOn(environmentService, 'get').mockReturnValue(undefined);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(undefined);
const mockContext = {
switchToHttp: () => ({
@ -52,7 +52,7 @@ describe('CloudflareSecretMatchGuard.canActivate', () => {
it('should return false if an error occurs', () => {
const mockRequest = { headers: {} };
jest.spyOn(environmentService, 'get').mockReturnValue('valid-secret');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('valid-secret');
const mockContext = {
switchToHttp: () => ({

View File

@ -1,18 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CustomHostnameCreateResponse } from 'cloudflare/resources/custom-hostnames/custom-hostnames';
import Cloudflare from 'cloudflare';
import { CustomHostnameCreateResponse } from 'cloudflare/resources/custom-hostnames/custom-hostnames';
import { DomainManagerException } from 'src/engine/core-modules/domain-manager/domain-manager.exception';
import { CustomDomainService } from 'src/engine/core-modules/domain-manager/services/custom-domain.service';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { DomainManagerException } from 'src/engine/core-modules/domain-manager/domain-manager.exception';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
jest.mock('cloudflare');
describe('CustomDomainService', () => {
let customDomainService: CustomDomainService;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
let domainManagerService: DomainManagerService;
beforeEach(async () => {
@ -20,7 +20,7 @@ describe('CustomDomainService', () => {
providers: [
CustomDomainService,
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -35,7 +35,7 @@ describe('CustomDomainService', () => {
}).compile();
customDomainService = module.get<CustomDomainService>(CustomDomainService);
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
domainManagerService =
module.get<DomainManagerService>(DomainManagerService);
@ -52,11 +52,11 @@ describe('CustomDomainService', () => {
it('should initialize cloudflareClient when CLOUDFLARE_API_KEY is defined', () => {
const mockApiKey = 'test-api-key';
jest.spyOn(environmentService, 'get').mockReturnValue(mockApiKey);
jest.spyOn(twentyConfigService, 'get').mockReturnValue(mockApiKey);
const instance = new CustomDomainService(environmentService, {} as any);
const instance = new CustomDomainService(twentyConfigService, {} as any);
expect(environmentService.get).toHaveBeenCalledWith('CLOUDFLARE_API_KEY');
expect(twentyConfigService.get).toHaveBeenCalledWith('CLOUDFLARE_API_KEY');
expect(Cloudflare).toHaveBeenCalledWith({ apiToken: mockApiKey });
expect(instance.cloudflareClient).toBeDefined();
});
@ -89,7 +89,7 @@ describe('CustomDomainService', () => {
jest
.spyOn(customDomainService, 'getCustomDomainDetails')
.mockResolvedValueOnce(undefined);
jest.spyOn(environmentService, 'get').mockReturnValue('test-zone-id');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('test-zone-id');
(customDomainService as any).cloudflareClient = cloudflareMock;
await customDomainService.registerCustomDomain(customDomain);
@ -111,7 +111,7 @@ describe('CustomDomainService', () => {
},
};
jest.spyOn(environmentService, 'get').mockReturnValue('test-zone-id');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('test-zone-id');
(customDomainService as any).cloudflareClient = cloudflareMock;
const result =
@ -137,7 +137,7 @@ describe('CustomDomainService', () => {
},
};
jest.spyOn(environmentService, 'get').mockReturnValue('test-zone-id');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('test-zone-id');
jest
.spyOn(domainManagerService, 'getFrontUrl')
@ -175,7 +175,7 @@ describe('CustomDomainService', () => {
},
};
jest.spyOn(environmentService, 'get').mockReturnValue('test-zone-id');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('test-zone-id');
jest
.spyOn(domainManagerService, 'getFrontUrl')
.mockReturnValue(new URL('https://front.domain'));
@ -199,7 +199,7 @@ describe('CustomDomainService', () => {
},
};
jest.spyOn(environmentService, 'get').mockReturnValue('test-zone-id');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('test-zone-id');
(customDomainService as any).cloudflareClient = cloudflareMock;
await expect(
@ -249,7 +249,7 @@ describe('CustomDomainService', () => {
},
};
jest.spyOn(environmentService, 'get').mockReturnValue('test-zone-id');
jest.spyOn(twentyConfigService, 'get').mockReturnValue('test-zone-id');
(customDomainService as any).cloudflareClient = cloudflareMock;
await expect(

View File

@ -9,21 +9,21 @@ import {
DomainManagerExceptionCode,
} from 'src/engine/core-modules/domain-manager/domain-manager.exception';
import { CustomDomainValidRecords } from 'src/engine/core-modules/domain-manager/dtos/custom-domain-valid-records';
import { domainManagerValidator } from 'src/engine/core-modules/domain-manager/validator/cloudflare.validate';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { domainManagerValidator } from 'src/engine/core-modules/domain-manager/validator/cloudflare.validate';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@Injectable()
export class CustomDomainService {
cloudflareClient?: Cloudflare;
constructor(
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
private readonly domainManagerService: DomainManagerService,
) {
if (this.environmentService.get('CLOUDFLARE_API_KEY')) {
if (this.twentyConfigService.get('CLOUDFLARE_API_KEY')) {
this.cloudflareClient = new Cloudflare({
apiToken: this.environmentService.get('CLOUDFLARE_API_KEY'),
apiToken: this.twentyConfigService.get('CLOUDFLARE_API_KEY'),
});
}
}
@ -39,7 +39,7 @@ export class CustomDomainService {
}
return await this.cloudflareClient.customHostnames.create({
zone_id: this.environmentService.get('CLOUDFLARE_ZONE_ID'),
zone_id: this.twentyConfigService.get('CLOUDFLARE_ZONE_ID'),
hostname: customDomain,
ssl: {
method: 'txt',
@ -63,7 +63,7 @@ export class CustomDomainService {
domainManagerValidator.isCloudflareInstanceDefined(this.cloudflareClient);
const response = await this.cloudflareClient.customHostnames.list({
zone_id: this.environmentService.get('CLOUDFLARE_ZONE_ID'),
zone_id: this.twentyConfigService.get('CLOUDFLARE_ZONE_ID'),
hostname: customDomain,
});
@ -163,7 +163,7 @@ export class CustomDomainService {
if (customHostname) {
await this.cloudflareClient.customHostnames.delete(customHostname.id, {
zone_id: this.environmentService.get('CLOUDFLARE_ZONE_ID'),
zone_id: this.twentyConfigService.get('CLOUDFLARE_ZONE_ID'),
});
}
} catch (err) {
@ -175,7 +175,7 @@ export class CustomDomainService {
domainManagerValidator.isCloudflareInstanceDefined(this.cloudflareClient);
await this.cloudflareClient.customHostnames.delete(customHostnameId, {
zone_id: this.environmentService.get('CLOUDFLARE_ZONE_ID'),
zone_id: this.twentyConfigService.get('CLOUDFLARE_ZONE_ID'),
});
}

View File

@ -3,7 +3,7 @@ import { getRepositoryToken } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { DomainManagerService } from './domain-manager.service';
@ -12,7 +12,7 @@ describe('DomainManagerService', () => {
describe('getWorkspaceUrls', () => {
it('should return a URL containing the correct customDomain if customDomain is provided', () => {
jest
.spyOn(environmentService, 'get')
.spyOn(twentyConfigService, 'get')
.mockImplementation((key: string) => {
const env = {
FRONTEND_URL: 'https://example.com',
@ -35,7 +35,7 @@ describe('DomainManagerService', () => {
it('should return a URL containing the correct subdomain if customDomain is not provided but subdomain is', () => {
jest
.spyOn(environmentService, 'get')
.spyOn(twentyConfigService, 'get')
.mockImplementation((key: string) => {
const env = {
FRONTEND_URL: 'https://example.com',
@ -58,7 +58,7 @@ describe('DomainManagerService', () => {
});
});
let domainManagerService: DomainManagerService;
let environmentService: EnvironmentService;
let twentyConfigService: TwentyConfigService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
@ -69,7 +69,7 @@ describe('DomainManagerService', () => {
useClass: Repository,
},
{
provide: EnvironmentService,
provide: TwentyConfigService,
useValue: {
get: jest.fn(),
},
@ -79,13 +79,13 @@ describe('DomainManagerService', () => {
domainManagerService =
module.get<DomainManagerService>(DomainManagerService);
environmentService = module.get<EnvironmentService>(EnvironmentService);
twentyConfigService = module.get<TwentyConfigService>(TwentyConfigService);
});
describe('buildBaseUrl', () => {
it('should build the base URL from environment variables', () => {
jest
.spyOn(environmentService, 'get')
.spyOn(twentyConfigService, 'get')
.mockImplementation((key: string) => {
const env = {
FRONTEND_URL: 'https://example.com',
@ -101,7 +101,7 @@ describe('DomainManagerService', () => {
it('should append default subdomain if multiworkspace is enabled', () => {
jest
.spyOn(environmentService, 'get')
.spyOn(twentyConfigService, 'get')
.mockImplementation((key: string) => {
const env = {
FRONTEND_URL: 'https://example.com',
@ -121,7 +121,7 @@ describe('DomainManagerService', () => {
describe('buildWorkspaceURL', () => {
it('should build workspace URL with given subdomain', () => {
jest
.spyOn(environmentService, 'get')
.spyOn(twentyConfigService, 'get')
.mockImplementation((key: string) => {
const env = {
FRONTEND_URL: 'https://example.com',
@ -145,7 +145,7 @@ describe('DomainManagerService', () => {
it('should set the pathname if provided', () => {
jest
.spyOn(environmentService, 'get')
.spyOn(twentyConfigService, 'get')
.mockImplementation((key: string) => {
const env = {
FRONTEND_URL: 'https://example.com',
@ -168,7 +168,7 @@ describe('DomainManagerService', () => {
it('should set the search parameters if provided', () => {
jest
.spyOn(environmentService, 'get')
.spyOn(twentyConfigService, 'get')
.mockImplementation((key: string) => {
const env = {
FRONTEND_URL: 'https://example.com',

View File

@ -10,7 +10,7 @@ import { CustomDomainValidRecords } from 'src/engine/core-modules/domain-manager
import { generateRandomSubdomain } from 'src/engine/core-modules/domain-manager/utils/generate-random-subdomain';
import { getSubdomainFromEmail } from 'src/engine/core-modules/domain-manager/utils/get-subdomain-from-email';
import { getSubdomainNameFromDisplayName } from 'src/engine/core-modules/domain-manager/utils/get-subdomain-name-from-display-name';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
@ -19,13 +19,13 @@ export class DomainManagerService {
constructor(
@InjectRepository(Workspace, 'core')
private readonly workspaceRepository: Repository<Workspace>,
private readonly environmentService: EnvironmentService,
private readonly twentyConfigService: TwentyConfigService,
) {}
getFrontUrl() {
return new URL(
this.environmentService.get('FRONTEND_URL') ??
this.environmentService.get('SERVER_URL'),
this.twentyConfigService.get('FRONTEND_URL') ??
this.twentyConfigService.get('SERVER_URL'),
);
}
@ -33,10 +33,10 @@ export class DomainManagerService {
const baseUrl = this.getFrontUrl();
if (
this.environmentService.get('IS_MULTIWORKSPACE_ENABLED') &&
this.environmentService.get('DEFAULT_SUBDOMAIN')
this.twentyConfigService.get('IS_MULTIWORKSPACE_ENABLED') &&
this.twentyConfigService.get('DEFAULT_SUBDOMAIN')
) {
baseUrl.hostname = `${this.environmentService.get('DEFAULT_SUBDOMAIN')}.${baseUrl.hostname}`;
baseUrl.hostname = `${this.twentyConfigService.get('DEFAULT_SUBDOMAIN')}.${baseUrl.hostname}`;
}
return baseUrl;
@ -122,7 +122,7 @@ export class DomainManagerService {
}
isDefaultSubdomain(subdomain: string) {
return subdomain === this.environmentService.get('DEFAULT_SUBDOMAIN');
return subdomain === this.twentyConfigService.get('DEFAULT_SUBDOMAIN');
}
computeRedirectErrorUrl(
@ -139,7 +139,7 @@ export class DomainManagerService {
}
private async getDefaultWorkspace() {
if (this.environmentService.get('IS_MULTIWORKSPACE_ENABLED')) {
if (this.twentyConfigService.get('IS_MULTIWORKSPACE_ENABLED')) {
throw new Error(
'Default workspace does not exist when multi-workspace is enabled',
);
@ -171,7 +171,7 @@ export class DomainManagerService {
}
async getWorkspaceByOriginOrDefaultWorkspace(origin: string) {
if (!this.environmentService.get('IS_MULTIWORKSPACE_ENABLED')) {
if (!this.twentyConfigService.get('IS_MULTIWORKSPACE_ENABLED')) {
return this.getDefaultWorkspace();
}
@ -222,7 +222,7 @@ export class DomainManagerService {
private getTwentyWorkspaceUrl(subdomain: string) {
const url = this.getFrontUrl();
url.hostname = this.environmentService.get('IS_MULTIWORKSPACE_ENABLED')
url.hostname = this.twentyConfigService.get('IS_MULTIWORKSPACE_ENABLED')
? `${subdomain}.${url.hostname}`
: url.hostname;
@ -234,7 +234,7 @@ export class DomainManagerService {
) {
if (!workspace) {
return {
subdomain: this.environmentService.get('DEFAULT_SUBDOMAIN'),
subdomain: this.twentyConfigService.get('DEFAULT_SUBDOMAIN'),
customDomain: null,
};
}

Some files were not shown because too many files have changed in this diff Show More