Refacto environment service (#4473)

* Refacto environment service

* Remove environment variable type
This commit is contained in:
Félix Malfait 2024-03-14 11:51:19 +01:00 committed by GitHub
parent 3caf860848
commit fd06d52a13
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 320 additions and 480 deletions

View File

@ -23,12 +23,13 @@ export class AnalyticsService {
workspace: Workspace | undefined,
request: Request,
) {
if (!this.environmentService.isTelemetryEnabled()) {
if (!this.environmentService.get('TELEMETRY_ENABLED')) {
return { success: true };
}
const anonymizationEnabled =
this.environmentService.isTelemetryAnonymizationEnabled();
const anonymizationEnabled = this.environmentService.get(
'TELEMETRY_ANONYMIZATION_ENABLED',
);
const data = {
type: createEventInput.type,

View File

@ -47,7 +47,7 @@ export class ApiRestQueryBuilderFactory {
if (!objectMetadataItems.length) {
throw new BadRequestException(
`No object was found for the workspace associated with this API key. You may generate a new one here ${this.environmentService.getFrontBaseUrl()}/settings/developers`,
`No object was found for the workspace associated with this API key. You may generate a new one here ${this.environmentService.get('FRONT_BASE_URL')}/settings/developers`,
);
}

View File

@ -30,9 +30,9 @@ import { AuthService } from './services/auth.service';
const jwtModule = JwtModule.registerAsync({
useFactory: async (environmentService: EnvironmentService) => {
return {
secret: environmentService.getAccessTokenSecret(),
secret: environmentService.get('ACCESS_TOKEN_SECRET'),
signOptions: {
expiresIn: environmentService.getAccessTokenExpiresIn(),
expiresIn: environmentService.get('ACCESS_TOKEN_EXPIRES_IN'),
},
};
},

View File

@ -37,7 +37,7 @@ export class GoogleAPIsAuthController {
const { workspaceMemberId, workspaceId } =
await this.tokenService.verifyTransientToken(transientToken);
const demoWorkspaceIds = this.environmentService.getDemoWorkspaceIds();
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
if (demoWorkspaceIds.includes(workspaceId)) {
throw new Error('Cannot connect Google account to demo workspace');
@ -57,7 +57,7 @@ export class GoogleAPIsAuthController {
});
return res.redirect(
`${this.environmentService.getFrontBaseUrl()}/settings/accounts`,
`${this.environmentService.get('FRONT_BASE_URL')}/settings/accounts`,
);
}
}

View File

@ -37,7 +37,7 @@ export class GoogleGmailAuthController {
const { workspaceMemberId, workspaceId } =
await this.tokenService.verifyTransientToken(transientToken);
const demoWorkspaceIds = this.environmentService.getDemoWorkspaceIds();
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
if (demoWorkspaceIds.includes(workspaceId)) {
throw new Error('Cannot connect Gmail account to demo workspace');
@ -58,7 +58,7 @@ export class GoogleGmailAuthController {
});
return res.redirect(
`${this.environmentService.getFrontBaseUrl()}/settings/accounts`,
`${this.environmentService.get('FRONT_BASE_URL')}/settings/accounts`,
);
}
}

View File

@ -11,8 +11,8 @@ export class GoogleAPIsProviderEnabledGuard implements CanActivate {
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
if (
!this.environmentService.isMessagingProviderGmailEnabled() &&
!this.environmentService.isCalendarProviderGoogleEnabled()
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
!this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
) {
throw new NotFoundException('Google apis auth is not enabled');
}

View File

@ -0,0 +1,21 @@
import { Injectable, CanActivate, NotFoundException } from '@nestjs/common';
import { Observable } from 'rxjs';
import { GoogleAPIsStrategy } from 'src/core/auth/strategies/google-apis.auth.strategy';
import { EnvironmentService } from 'src/integrations/environment/environment.service';
@Injectable()
export class GoogleGmailProviderEnabledGuard implements CanActivate {
constructor(private readonly environmentService: EnvironmentService) {}
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
if (!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED')) {
throw new NotFoundException('Gmail auth is not enabled');
}
new GoogleAPIsStrategy(this.environmentService);
return true;
}
}

View File

@ -10,7 +10,7 @@ export class GoogleProviderEnabledGuard implements CanActivate {
constructor(private readonly environmentService: EnvironmentService) {}
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
if (!this.environmentService.isAuthGoogleEnabled()) {
if (!this.environmentService.get('AUTH_GOOGLE_ENABLED')) {
throw new NotFoundException('Google auth is not enabled');
}

View File

@ -194,7 +194,7 @@ export class AuthService {
const emailTemplate = PasswordUpdateNotifyEmail({
userName: `${user.firstName} ${user.lastName}`,
email: user.email,
link: this.environmentService.getFrontBaseUrl(),
link: this.environmentService.get('FRONT_BASE_URL'),
});
const html = render(emailTemplate, {
@ -205,7 +205,7 @@ export class AuthService {
});
this.emailService.send({
from: `${this.environmentService.getEmailFromName()} <${this.environmentService.getEmailFromAddress()}>`,
from: `${this.environmentService.get('EMAIL_FROM_NAME')} <${this.environmentService.get('EMAIL_FROM_ADDRESS')}>`,
to: user.email,
subject: 'Your Password Has Been Successfully Changed',
text,

View File

@ -88,7 +88,7 @@ export class GoogleAPIsService {
],
);
if (this.environmentService.isMessagingProviderGmailEnabled()) {
if (this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED')) {
await manager.query(
`INSERT INTO ${dataSourceMetadata.schema}."messageChannel" ("visibility", "handle", "connectedAccountId", "type") VALUES ($1, $2, $3, $4)`,
['share_everything', handle, connectedAccountId, 'email'],
@ -96,7 +96,7 @@ export class GoogleAPIsService {
}
if (
this.environmentService.isCalendarProviderGoogleEnabled() &&
this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED') &&
IsCalendarEnabled
) {
await manager.query(
@ -106,7 +106,7 @@ export class GoogleAPIsService {
}
});
if (this.environmentService.isMessagingProviderGmailEnabled()) {
if (this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED')) {
await this.messageQueueService.add<GmailFullSyncJobData>(
GmailFullSyncJob.name,
{
@ -120,7 +120,7 @@ export class GoogleAPIsService {
}
if (
this.environmentService.isCalendarProviderGoogleEnabled() &&
this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED') &&
IsCalendarEnabled
) {
await this.calendarQueueService.add<GoogleCalendarFullSyncJobData>(

View File

@ -190,7 +190,7 @@ export class SignUpService {
}
assert(
!this.environmentService.isSignUpDisabled(),
!this.environmentService.get('IS_SIGN_UP_DISABLED'),
'Sign up is disabled',
ForbiddenException,
);

View File

@ -63,7 +63,7 @@ export class TokenService {
userId: string,
workspaceId?: string,
): Promise<AuthToken> {
const expiresIn = this.environmentService.getAccessTokenExpiresIn();
const expiresIn = this.environmentService.get('ACCESS_TOKEN_EXPIRES_IN');
assert(expiresIn, '', InternalServerErrorException);
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
@ -93,8 +93,8 @@ export class TokenService {
}
async generateRefreshToken(userId: string): Promise<AuthToken> {
const secret = this.environmentService.getRefreshTokenSecret();
const expiresIn = this.environmentService.getRefreshTokenExpiresIn();
const secret = this.environmentService.get('REFRESH_TOKEN_SECRET');
const expiresIn = this.environmentService.get('REFRESH_TOKEN_EXPIRES_IN');
assert(expiresIn, '', InternalServerErrorException);
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
@ -124,8 +124,8 @@ export class TokenService {
}
async generateLoginToken(email: string): Promise<AuthToken> {
const secret = this.environmentService.getLoginTokenSecret();
const expiresIn = this.environmentService.getLoginTokenExpiresIn();
const secret = this.environmentService.get('LOGIN_TOKEN_SECRET');
const expiresIn = this.environmentService.get('LOGIN_TOKEN_EXPIRES_IN');
assert(expiresIn, '', InternalServerErrorException);
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
@ -146,8 +146,8 @@ export class TokenService {
workspaceMemberId: string,
workspaceId: string,
): Promise<AuthToken> {
const secret = this.environmentService.getLoginTokenSecret();
const expiresIn = this.environmentService.getTransientTokenExpiresIn();
const secret = this.environmentService.get('LOGIN_TOKEN_SECRET');
const expiresIn = this.environmentService.get('SHORT_TERM_TOKEN_EXPIRES_IN');
assert(expiresIn, '', InternalServerErrorException);
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
@ -176,7 +176,7 @@ export class TokenService {
const jwtPayload = {
sub: workspaceId,
};
const secret = this.environmentService.getAccessTokenSecret();
const secret = this.environmentService.get('ACCESS_TOKEN_SECRET');
let expiresIn: string | number;
if (expiresAt) {
@ -184,7 +184,7 @@ export class TokenService {
(new Date(expiresAt).getTime() - new Date().getTime()) / 1000,
);
} else {
expiresIn = this.environmentService.getApiTokenExpiresIn();
expiresIn = this.environmentService.get('API_TOKEN_EXPIRES_IN');
}
const token = this.jwtService.sign(jwtPayload, {
secret,
@ -209,7 +209,7 @@ export class TokenService {
}
const decoded = await this.verifyJwt(
token,
this.environmentService.getAccessTokenSecret(),
this.environmentService.get('ACCESS_TOKEN_SECRET'),
);
const { user, workspace } = await this.jwtStrategy.validate(
@ -220,7 +220,7 @@ export class TokenService {
}
async verifyLoginToken(loginToken: string): Promise<string> {
const loginTokenSecret = this.environmentService.getLoginTokenSecret();
const loginTokenSecret = this.environmentService.get('LOGIN_TOKEN_SECRET');
const payload = await this.verifyJwt(loginToken, loginTokenSecret);
@ -231,7 +231,7 @@ export class TokenService {
workspaceMemberId: string;
workspaceId: string;
}> {
const transientTokenSecret = this.environmentService.getLoginTokenSecret();
const transientTokenSecret = this.environmentService.get('LOGIN_TOKEN_SECRET');
const payload = await this.verifyJwt(transientToken, transientTokenSecret);
@ -281,8 +281,8 @@ export class TokenService {
}
async verifyRefreshToken(refreshToken: string) {
const secret = this.environmentService.getRefreshTokenSecret();
const coolDown = this.environmentService.getRefreshTokenCoolDown();
const secret = this.environmentService.get('REFRESH_TOKEN_SECRET');
const coolDown = this.environmentService.get('REFRESH_TOKEN_COOL_DOWN');
const jwtPayload = await this.verifyJwt(refreshToken, secret);
assert(
@ -382,7 +382,7 @@ export class TokenService {
assert(user, 'User not found', NotFoundException);
const expiresIn = this.environmentService.getPasswordResetTokenExpiresIn();
const expiresIn = this.environmentService.get('PASSWORD_RESET_TOKEN_EXPIRES_IN');
assert(
expiresIn,
@ -439,7 +439,7 @@ export class TokenService {
assert(user, 'User not found', NotFoundException);
const frontBaseURL = this.environmentService.getFrontBaseUrl();
const frontBaseURL = this.environmentService.get('FRONT_BASE_URL');
const resetLink = `${frontBaseURL}/reset-password/${resetToken.passwordResetToken}`;
const emailData = {
@ -465,7 +465,7 @@ export class TokenService {
});
this.emailService.send({
from: `${this.environmentService.getEmailFromName()} <${this.environmentService.getEmailFromAddress()}>`,
from: `${this.environmentService.get('EMAIL_FROM_NAME')} <${this.environmentService.get('EMAIL_FROM_ADDRESS')}>`,
to: email,
subject: 'Action Needed to Reset Password',
text,

View File

@ -27,20 +27,20 @@ export class GoogleAPIsStrategy extends PassportStrategy(
constructor(environmentService: EnvironmentService) {
const scope = ['email', 'profile'];
if (environmentService.isMessagingProviderGmailEnabled()) {
if (environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED')) {
scope.push('https://www.googleapis.com/auth/gmail.readonly');
}
if (environmentService.isCalendarProviderGoogleEnabled()) {
if (environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')) {
scope.push('https://www.googleapis.com/auth/calendar');
}
super({
clientID: environmentService.getAuthGoogleClientId(),
clientSecret: environmentService.getAuthGoogleClientSecret(),
callbackURL: environmentService.isCalendarProviderGoogleEnabled()
? environmentService.getAuthGoogleAPIsCallbackUrl()
: environmentService.getMessagingProviderGmailCallbackUrl(),
clientID: environmentService.get('AUTH_GOOGLE_CLIENT_ID'),
clientSecret: environmentService.get('AUTH_GOOGLE_CLIENT_SECRET'),
callbackURL: environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
? environmentService.get('AUTH_GOOGLE_APIS_CALLBACK_URL')
: environmentService.get('MESSAGING_PROVIDER_GMAIL_CALLBACK_URL'),
scope,
passReqToCallback: true,
});

View File

@ -20,9 +20,9 @@ export type GoogleRequest = Request & {
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
constructor(environmentService: EnvironmentService) {
super({
clientID: environmentService.getAuthGoogleClientId(),
clientSecret: environmentService.getAuthGoogleClientSecret(),
callbackURL: environmentService.getAuthGoogleCallbackUrl(),
clientID: environmentService.get('AUTH_GOOGLE_CLIENT_ID'),
clientSecret: environmentService.get('AUTH_GOOGLE_CLIENT_SECRET'),
callbackURL: environmentService.get('AUTH_GOOGLE_CALLBACK_URL'),
scope: ['email', 'profile'],
passReqToCallback: true,
});

View File

@ -33,7 +33,7 @@ export class JwtAuthStrategy extends PassportStrategy(Strategy, 'jwt') {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: environmentService.getAccessTokenSecret(),
secretOrKey: environmentService.get('ACCESS_TOKEN_SECRET'),
});
}

View File

@ -42,7 +42,7 @@ export class BillingService {
getProductStripeId(product: AvailableProduct) {
if (product === AvailableProduct.BasePlan) {
return this.environmentService.getBillingStripeBasePlanProductId();
return this.environmentService.get('BILLING_STRIPE_BASE_PLAN_PRODUCT_ID');
}
}
@ -98,7 +98,7 @@ export class BillingService {
async getBillingSubscriptionItem(
workspaceId: string,
stripeProductId = this.environmentService.getBillingStripeBasePlanProductId(),
stripeProductId = this.environmentService.get('BILLING_STRIPE_BASE_PLAN_PRODUCT_ID'),
) {
const billingSubscription = await this.getCurrentBillingSubscription({
workspaceId,
@ -134,7 +134,7 @@ export class BillingService {
where: { workspaceId },
});
const frontBaseUrl = this.environmentService.getFrontBaseUrl();
const frontBaseUrl = this.environmentService.get('FRONT_BASE_URL');
const returnUrl = returnUrlPath
? frontBaseUrl + returnUrlPath
: frontBaseUrl;
@ -154,7 +154,7 @@ export class BillingService {
priceId: string,
successUrlPath?: string,
): Promise<string> {
const frontBaseUrl = this.environmentService.getFrontBaseUrl();
const frontBaseUrl = this.environmentService.get('FRONT_BASE_URL');
const successUrl = successUrlPath
? frontBaseUrl + successUrlPath
: frontBaseUrl;

View File

@ -12,14 +12,14 @@ export class StripeService {
constructor(private readonly environmentService: EnvironmentService) {
this.stripe = new Stripe(
this.environmentService.getBillingStripeApiKey(),
this.environmentService.get('BILLING_STRIPE_API_KEY'),
{},
);
}
constructEventFromPayload(signature: string, payload: Buffer) {
const webhookSecret =
this.environmentService.getBillingStripeWebhookSecret();
this.environmentService.get('BILLING_STRIPE_WEBHOOK_SECRET');
return this.stripe.webhooks.constructEvent(
payload,
@ -48,7 +48,7 @@ export class StripeService {
): Promise<Stripe.BillingPortal.Session> {
return await this.stripe.billingPortal.sessions.create({
customer: stripeCustomerId,
return_url: returnUrl ?? this.environmentService.getFrontBaseUrl(),
return_url: returnUrl ?? this.environmentService.get('FRONT_BASE_URL'),
});
}
@ -73,7 +73,7 @@ export class StripeService {
workspaceId: user.defaultWorkspace.id,
},
trial_period_days:
this.environmentService.getBillingFreeTrialDurationInDays(),
this.environmentService.get('BILLING_FREE_TRIAL_DURATION_IN_DAYS'),
},
automatic_tax: { enabled: true },
tax_id_collection: { enabled: true },

View File

@ -12,30 +12,34 @@ export class ClientConfigResolver {
async clientConfig(): Promise<ClientConfig> {
const clientConfig: ClientConfig = {
authProviders: {
google: this.environmentService.isAuthGoogleEnabled(),
google: this.environmentService.get('AUTH_GOOGLE_ENABLED'),
magicLink: false,
password: true,
},
telemetry: {
enabled: this.environmentService.isTelemetryEnabled(),
anonymizationEnabled:
this.environmentService.isTelemetryAnonymizationEnabled(),
enabled: this.environmentService.get('TELEMETRY_ENABLED'),
anonymizationEnabled: this.environmentService.get(
'TELEMETRY_ANONYMIZATION_ENABLED',
),
},
billing: {
isBillingEnabled: this.environmentService.isBillingEnabled(),
billingUrl: this.environmentService.getBillingUrl(),
billingFreeTrialDurationInDays:
this.environmentService.getBillingFreeTrialDurationInDays(),
isBillingEnabled: this.environmentService.get('IS_BILLING_ENABLED'),
billingUrl: this.environmentService.get('BILLING_PLAN_REQUIRED_LINK'),
billingFreeTrialDurationInDays: this.environmentService.get(
'BILLING_FREE_TRIAL_DURATION_IN_DAYS',
),
},
signInPrefilled: this.environmentService.isSignInPrefilled(),
signUpDisabled: this.environmentService.isSignUpDisabled(),
debugMode: this.environmentService.isDebugMode(),
signInPrefilled: this.environmentService.get('SIGN_IN_PREFILLED'),
signUpDisabled: this.environmentService.get('IS_SIGN_UP_DISABLED'),
debugMode: this.environmentService.get('DEBUG_MODE'),
support: {
supportDriver: this.environmentService.getSupportDriver(),
supportFrontChatId: this.environmentService.getSupportFrontChatId(),
supportDriver: this.environmentService.get('SUPPORT_DRIVER'),
supportFrontChatId: this.environmentService.get(
'SUPPORT_FRONT_CHAT_ID',
),
},
sentry: {
dsn: this.environmentService.getSentryDSN(),
dsn: this.environmentService.get('SENTRY_DSN'),
},
};

View File

@ -37,7 +37,7 @@ export class IntelligenceService {
'https://openrouter.ai/api/v1/chat/completions',
{
headers: {
Authorization: `Bearer ${this.environmentService.getOpenRouterApiKey()}`,
Authorization: `Bearer ${this.environmentService.get('OPENROUTER_API_KEY')}`,
'HTTP-Referer': `https://twenty.com`,
'X-Title': `Twenty CRM`,
'Content-Type': 'application/json',

View File

@ -76,10 +76,10 @@ export class UserResolver {
nullable: true,
})
supportUserHash(@Parent() parent: User): string | null {
if (this.environmentService.getSupportDriver() !== SupportDriver.Front) {
if (this.environmentService.get('SUPPORT_DRIVER') !== SupportDriver.Front) {
return null;
}
const key = this.environmentService.getSupportFrontHMACKey();
const key = this.environmentService.get('SUPPORT_FRONT_HMAC_KEY');
return getHMACKey(parent.email, key);
}
@ -111,7 +111,7 @@ export class UserResolver {
@Mutation(() => User)
async deleteUser(@AuthUser() { id: userId, defaultWorkspace }: User) {
// Get the list of demo workspace IDs
const demoWorkspaceIds = this.environmentService.getDemoWorkspaceIds();
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
const currentUserWorkspaceId = defaultWorkspace.id;

View File

@ -91,7 +91,7 @@ export class WorkspaceResolver {
@Mutation(() => Workspace)
async deleteCurrentWorkspace(@AuthWorkspace() { id }: Workspace) {
const demoWorkspaceIds = this.environmentService.getDemoWorkspaceIds();
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
// Check if the id is in the list of demo workspaceIds
if (demoWorkspaceIds.includes(id)) {

View File

@ -19,14 +19,14 @@ export class DataSeedDemoWorkspaceService {
async seedDemo(): Promise<void> {
try {
const dataSource = new DataSource({
url: this.environmentService.getPGDatabaseUrl(),
url: this.environmentService.get('PG_DATABASE_URL'),
type: 'postgres',
logging: true,
schema: 'public',
});
await dataSource.initialize();
const demoWorkspaceIds = this.environmentService.getDemoWorkspaceIds();
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
if (demoWorkspaceIds.length === 0) {
throw new Error(

View File

@ -38,7 +38,7 @@ export class DataSeedWorkspaceCommand extends CommandRunner {
async run(): Promise<void> {
try {
const dataSource = new DataSource({
url: this.environmentService.getPGDatabaseUrl(),
url: this.environmentService.get('PG_DATABASE_URL'),
type: 'postgres',
logging: true,
schema: 'core',

View File

@ -20,7 +20,7 @@ export class TypeORMService implements OnModuleInit, OnModuleDestroy {
constructor(private readonly environmentService: EnvironmentService) {
this.mainDataSource = new DataSource({
url: environmentService.getPGDatabaseUrl(),
url: environmentService.get('PG_DATABASE_URL'),
type: 'postgres',
logging: false,
schema: 'core',
@ -83,9 +83,9 @@ export class TypeORMService implements OnModuleInit, OnModuleDestroy {
const schema = dataSource.schema;
const workspaceDataSource = new DataSource({
url: dataSource.url ?? this.environmentService.getPGDatabaseUrl(),
url: dataSource.url ?? this.environmentService.get('PG_DATABASE_URL'),
type: 'postgres',
logging: this.environmentService.isDebugMode()
logging: this.environmentService.get('DEBUG_MODE')
? ['query', 'error']
: ['error'],
schema,

View File

@ -46,11 +46,11 @@ export class GraphQLConfigService
) {}
createGqlOptions(): YogaDriverConfig {
const isDebugMode = this.environmentService.isDebugMode();
const isDebugMode = this.environmentService.get('DEBUG_MODE');
const plugins = [
useThrottler({
ttl: this.environmentService.getApiRateLimitingTtl(),
limit: this.environmentService.getApiRateLimitingLimit(),
ttl: this.environmentService.get('API_RATE_LIMITING_TTL'),
limit: this.environmentService.get('API_RATE_LIMITING_LIMIT'),
identifyFn: (context) => {
return context.user?.id ?? context.req.ip ?? 'anonymous';
},

View File

@ -8,8 +8,8 @@ import { EnvironmentService } from 'src/integrations/environment/environment.ser
export const cacheStorageModuleFactory = (
environmentService: EnvironmentService,
): CacheModuleOptions => {
const cacheStorageType = environmentService.getCacheStorageType();
const cacheStorageTtl = environmentService.getCacheStorageTtl();
const cacheStorageType = environmentService.get('CACHE_STORAGE_TYPE');
const cacheStorageTtl = environmentService.get('CACHE_STORAGE_TTL');
const cacheModuleOptions: CacheModuleOptions = {
isGlobal: true,
ttl: cacheStorageTtl * 1000,
@ -20,8 +20,8 @@ export const cacheStorageModuleFactory = (
return cacheModuleOptions;
}
case CacheStorageType.Redis: {
const host = environmentService.getRedisHost();
const port = environmentService.getRedisPort();
const host = environmentService.get('REDIS_HOST');
const port = environmentService.get('REDIS_PORT');
if (!(host && port)) {
throw new Error(

View File

@ -8,17 +8,17 @@ import { EnvironmentService } from 'src/integrations/environment/environment.ser
export const emailModuleFactory = (
environmentService: EnvironmentService,
): EmailModuleOptions => {
const driver = environmentService.getEmailDriver();
const driver = environmentService.get('EMAIL_DRIVER');
switch (driver) {
case EmailDriver.Logger: {
return;
}
case EmailDriver.Smtp: {
const host = environmentService.getEmailHost();
const port = environmentService.getEmailPort();
const user = environmentService.getEmailUser();
const pass = environmentService.getEmailPassword();
const host = environmentService.get('EMAIL_SMTP_HOST');
const port = environmentService.get('EMAIL_SMTP_PORT');
const user = environmentService.get('EMAIL_SMTP_USER');
const pass = environmentService.get('EMAIL_SMTP_PASSWORD');
if (!(host && port)) {
throw new Error(

View File

@ -10,8 +10,11 @@ import {
validateSync,
IsBoolean,
IsNumber,
IsDefined,
} from 'class-validator';
import { EmailDriver } from 'src/integrations/email/interfaces/email.interface';
import { assert } from 'src/utils/assert';
import { CastToStringArray } from 'src/integrations/environment/decorators/cast-to-string-array.decorator';
import { ExceptionHandlerDriver } from 'src/integrations/exception-handler/interfaces';
@ -32,49 +35,49 @@ export class EnvironmentVariables {
@CastToBoolean()
@IsOptional()
@IsBoolean()
DEBUG_MODE?: boolean;
DEBUG_MODE: boolean;
@CastToBoolean()
@IsOptional()
@IsBoolean()
SIGN_IN_PREFILLED?: boolean;
SIGN_IN_PREFILLED: boolean;
@CastToBoolean()
@IsOptional()
@IsBoolean()
IS_BILLING_ENABLED?: boolean;
IS_BILLING_ENABLED: boolean;
@IsString()
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
BILLING_PLAN_REQUIRED_LINK?: string;
BILLING_PLAN_REQUIRED_LINK: string;
@IsString()
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
BILLING_STRIPE_BASE_PLAN_PRODUCT_ID?: string;
BILLING_STRIPE_BASE_PLAN_PRODUCT_ID: string;
@IsNumber()
@CastToPositiveNumber()
@IsOptional()
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
BILLING_FREE_TRIAL_DURATION_IN_DAYS?: number;
BILLING_FREE_TRIAL_DURATION_IN_DAYS: number;
@IsString()
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
BILLING_STRIPE_API_KEY?: string;
BILLING_STRIPE_API_KEY: string;
@IsString()
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
BILLING_STRIPE_WEBHOOK_SECRET?: string;
BILLING_STRIPE_WEBHOOK_SECRET: string;
@CastToBoolean()
@IsOptional()
@IsBoolean()
TELEMETRY_ENABLED?: boolean;
TELEMETRY_ENABLED: boolean;
@CastToBoolean()
@IsOptional()
@IsBoolean()
TELEMETRY_ANONYMIZATION_ENABLED?: boolean;
TELEMETRY_ANONYMIZATION_ENABLED: boolean;
@CastToPositiveNumber()
@IsNumber()
@ -82,6 +85,7 @@ export class EnvironmentVariables {
PORT: number;
// Database
@IsDefined()
@IsUrl({
protocols: ['postgres'],
require_tld: false,
@ -132,75 +136,79 @@ export class EnvironmentVariables {
@CastToBoolean()
@IsOptional()
@IsBoolean()
AUTH_GOOGLE_ENABLED?: boolean;
AUTH_GOOGLE_ENABLED: boolean;
@IsString()
@ValidateIf((env) => env.AUTH_GOOGLE_ENABLED === true)
AUTH_GOOGLE_CLIENT_ID?: string;
AUTH_GOOGLE_CLIENT_ID: string;
@IsString()
@ValidateIf((env) => env.AUTH_GOOGLE_ENABLED === true)
AUTH_GOOGLE_CLIENT_SECRET?: string;
AUTH_GOOGLE_CLIENT_SECRET: string;
@IsUrl({ require_tld: false })
@ValidateIf((env) => env.AUTH_GOOGLE_ENABLED === true)
AUTH_GOOGLE_CALLBACK_URL?: string;
AUTH_GOOGLE_CALLBACK_URL: string;
// Storage
@IsEnum(StorageDriverType)
@IsOptional()
STORAGE_TYPE?: StorageDriverType;
STORAGE_TYPE: StorageDriverType;
@ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3)
@IsAWSRegion()
STORAGE_S3_REGION?: AwsRegion;
STORAGE_S3_REGION: AwsRegion;
@ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3)
@IsString()
STORAGE_S3_NAME?: string;
STORAGE_S3_NAME: string;
@ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3)
@IsString()
STORAGE_S3_ENDPOINT: string;
@IsString()
@ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.Local)
STORAGE_LOCAL_PATH?: string;
STORAGE_LOCAL_PATH: string;
// Support
@IsEnum(SupportDriver)
@IsOptional()
SUPPORT_DRIVER?: SupportDriver;
SUPPORT_DRIVER: SupportDriver;
@ValidateIf((env) => env.SUPPORT_DRIVER === SupportDriver.Front)
@IsString()
SUPPORT_FRONT_CHAT_ID?: string;
SUPPORT_FRONT_CHAT_ID: string;
@ValidateIf((env) => env.SUPPORT_DRIVER === SupportDriver.Front)
@IsString()
SUPPORT_FRONT_HMAC_KEY?: string;
SUPPORT_FRONT_HMAC_KEY: string;
@IsEnum(LoggerDriverType)
@IsOptional()
LOGGER_DRIVER?: LoggerDriverType;
LOGGER_DRIVER: LoggerDriverType;
@IsEnum(ExceptionHandlerDriver)
@IsOptional()
EXCEPTION_HANDLER_DRIVER?: ExceptionHandlerDriver;
EXCEPTION_HANDLER_DRIVER: ExceptionHandlerDriver;
@CastToLogLevelArray()
@IsOptional()
LOG_LEVELS?: LogLevel[];
LOG_LEVELS: LogLevel[];
@CastToStringArray()
@IsOptional()
DEMO_WORKSPACE_IDS?: string[];
DEMO_WORKSPACE_IDS: string[];
@ValidateIf(
(env) => env.EXCEPTION_HANDLER_DRIVER === ExceptionHandlerDriver.Sentry,
)
@IsString()
SENTRY_DSN?: string;
SENTRY_DSN: string;
@IsDuration()
@IsOptional()
PASSWORD_RESET_TOKEN_EXPIRES_IN?: number;
PASSWORD_RESET_TOKEN_EXPIRES_IN: string;
@CastToPositiveNumber()
@IsNumber()
@ -220,13 +228,56 @@ export class EnvironmentVariables {
@CastToBoolean()
@IsOptional()
@IsBoolean()
IS_SIGN_UP_DISABLED?: boolean;
IS_SIGN_UP_DISABLED: boolean;
@CastToPositiveNumber()
@IsOptional()
@IsNumber()
MUTATION_MAXIMUM_RECORD_AFFECTED: number;
REDIS_HOST: string;
REDIS_PORT: number;
API_TOKEN_EXPIRES_IN: string;
SHORT_TERM_TOKEN_EXPIRES_IN: string;
MESSAGING_PROVIDER_GMAIL_ENABLED: boolean;
MESSAGING_PROVIDER_GMAIL_CALLBACK_URL: string;
MESSAGE_QUEUE_TYPE: string;
EMAIL_FROM_ADDRESS: string;
EMAIL_SYSTEM_ADDRESS: string;
EMAIL_FROM_NAME: string;
EMAIL_DRIVER: EmailDriver;
EMAIL_SMTP_HOST: string;
EMAIL_SMTP_PORT: number;
EMAIL_SMTP_USER: string;
EMAIL_SMTP_PASSWORD: string;
OPENROUTER_API_KEY: string;
API_RATE_LIMITING_TTL: number;
API_RATE_LIMITING_LIMIT: number;
CACHE_STORAGE_TYPE: string;
CACHE_STORAGE_TTL: number;
CALENDAR_PROVIDER_GOOGLE_ENABLED: boolean;
AUTH_GOOGLE_APIS_CALLBACK_URL: string;
}
export const validate = (config: Record<string, unknown>) => {
const validatedConfig = plainToClass(EnvironmentVariables, config);

View File

@ -0,0 +1,77 @@
import { EmailDriver } from 'src/integrations/email/interfaces/email.interface';
import { SupportDriver } from 'src/integrations/environment/interfaces/support.interface';
import { ExceptionHandlerDriver } from 'src/integrations/exception-handler/interfaces';
import { StorageDriverType } from 'src/integrations/file-storage/interfaces';
import { LoggerDriverType } from 'src/integrations/logger/interfaces';
import { MessageQueueDriverType } from 'src/integrations/message-queue/interfaces';
import { EnvironmentVariables } from 'src/integrations/environment/environment-variables';
const EnvironmentDefault = new EnvironmentVariables();
EnvironmentDefault.DEBUG_MODE = false;
EnvironmentDefault.SIGN_IN_PREFILLED = false;
EnvironmentDefault.IS_BILLING_ENABLED = false;
EnvironmentDefault.BILLING_PLAN_REQUIRED_LINK = '';
EnvironmentDefault.BILLING_STRIPE_BASE_PLAN_PRODUCT_ID = '';
EnvironmentDefault.BILLING_FREE_TRIAL_DURATION_IN_DAYS = 7;
EnvironmentDefault.BILLING_STRIPE_API_KEY = '';
EnvironmentDefault.BILLING_STRIPE_WEBHOOK_SECRET = '';
EnvironmentDefault.TELEMETRY_ENABLED = true;
EnvironmentDefault.TELEMETRY_ANONYMIZATION_ENABLED = true;
EnvironmentDefault.PORT = 3000;
EnvironmentDefault.REDIS_HOST = '127.0.0.1';
EnvironmentDefault.REDIS_PORT = 6379;
EnvironmentDefault.PG_DATABASE_URL = '';
EnvironmentDefault.FRONT_BASE_URL = '';
EnvironmentDefault.SERVER_URL = '';
EnvironmentDefault.ACCESS_TOKEN_SECRET = 'random_string';
EnvironmentDefault.ACCESS_TOKEN_EXPIRES_IN = '30m';
EnvironmentDefault.REFRESH_TOKEN_SECRET = 'random_string';
EnvironmentDefault.REFRESH_TOKEN_EXPIRES_IN = '30m';
EnvironmentDefault.REFRESH_TOKEN_COOL_DOWN = '1m';
EnvironmentDefault.LOGIN_TOKEN_SECRET = 'random_string';
EnvironmentDefault.LOGIN_TOKEN_EXPIRES_IN = '30m';
EnvironmentDefault.API_TOKEN_EXPIRES_IN = '100y';
EnvironmentDefault.SHORT_TERM_TOKEN_EXPIRES_IN = '5m';
EnvironmentDefault.FRONT_AUTH_CALLBACK_URL = '';
EnvironmentDefault.MESSAGING_PROVIDER_GMAIL_ENABLED = false;
EnvironmentDefault.MESSAGING_PROVIDER_GMAIL_CALLBACK_URL = '';
EnvironmentDefault.AUTH_GOOGLE_ENABLED = false;
EnvironmentDefault.AUTH_GOOGLE_CLIENT_ID = '';
EnvironmentDefault.AUTH_GOOGLE_CLIENT_SECRET = '';
EnvironmentDefault.AUTH_GOOGLE_CALLBACK_URL = '';
EnvironmentDefault.STORAGE_TYPE = StorageDriverType.Local;
EnvironmentDefault.STORAGE_S3_REGION = 'aws-east-1';
EnvironmentDefault.STORAGE_S3_NAME = '';
EnvironmentDefault.STORAGE_S3_ENDPOINT = '';
EnvironmentDefault.STORAGE_LOCAL_PATH = '.local-storage';
EnvironmentDefault.MESSAGE_QUEUE_TYPE = MessageQueueDriverType.Sync;
EnvironmentDefault.EMAIL_FROM_ADDRESS = 'noreply@yourdomain.com';
EnvironmentDefault.EMAIL_SYSTEM_ADDRESS = 'system@yourdomain.com';
EnvironmentDefault.EMAIL_FROM_NAME = 'John from Twenty';
EnvironmentDefault.EMAIL_DRIVER = EmailDriver.Logger;
EnvironmentDefault.EMAIL_SMTP_HOST = '';
EnvironmentDefault.EMAIL_SMTP_PORT = 587;
EnvironmentDefault.EMAIL_SMTP_USER = '';
EnvironmentDefault.EMAIL_SMTP_PASSWORD = '';
EnvironmentDefault.SUPPORT_DRIVER = SupportDriver.None;
EnvironmentDefault.SUPPORT_FRONT_CHAT_ID = '';
EnvironmentDefault.SUPPORT_FRONT_HMAC_KEY = '';
EnvironmentDefault.LOGGER_DRIVER = LoggerDriverType.Console;
EnvironmentDefault.EXCEPTION_HANDLER_DRIVER = ExceptionHandlerDriver.Console;
EnvironmentDefault.LOG_LEVELS = ['log', 'error', 'warn'];
EnvironmentDefault.SENTRY_DSN = '';
EnvironmentDefault.DEMO_WORKSPACE_IDS = [];
EnvironmentDefault.OPENROUTER_API_KEY = '';
EnvironmentDefault.PASSWORD_RESET_TOKEN_EXPIRES_IN = '5m';
EnvironmentDefault.WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION = 30;
EnvironmentDefault.WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION = 60;
EnvironmentDefault.IS_SIGN_UP_DISABLED = false;
EnvironmentDefault.API_RATE_LIMITING_TTL = 100;
EnvironmentDefault.API_RATE_LIMITING_LIMIT = 500;
EnvironmentDefault.MUTATION_MAXIMUM_RECORD_AFFECTED = 100;
EnvironmentDefault.CACHE_STORAGE_TYPE = 'memory';
EnvironmentDefault.CACHE_STORAGE_TTL = 3600 * 24 * 7;
export { EnvironmentDefault };

View File

@ -3,7 +3,7 @@ import { ConfigModule } from '@nestjs/config';
import { EnvironmentService } from './environment.service';
import { ConfigurableModuleClass } from './environment.module-definition';
import { validate } from './environment.validation';
import { validate } from './environment-variables';
@Global()
@Module({

View File

@ -1,92 +1,23 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { Injectable, LogLevel } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Request } from 'express';
import { EmailDriver } from 'src/integrations/email/interfaces/email.interface';
import { LoggerDriverType } from 'src/integrations/logger/interfaces';
import { ExceptionHandlerDriver } from 'src/integrations/exception-handler/interfaces';
import { StorageDriverType } from 'src/integrations/file-storage/interfaces';
import { MessageQueueDriverType } from 'src/integrations/message-queue/interfaces';
import { AwsRegion } from './interfaces/aws-region.interface';
import { SupportDriver } from './interfaces/support.interface';
import { EnvironmentVariables } from 'src/integrations/environment/environment-variables';
import { EnvironmentDefault } from 'src/integrations/environment/environment.default';
@Injectable()
export class EnvironmentService {
constructor(private configService: ConfigService) {}
isDebugMode(): boolean {
return this.configService.get<boolean>('DEBUG_MODE') ?? false;
}
isSignInPrefilled(): boolean {
return this.configService.get<boolean>('SIGN_IN_PREFILLED') ?? false;
}
isBillingEnabled() {
return this.configService.get<boolean>('IS_BILLING_ENABLED') ?? false;
}
getBillingUrl() {
return this.configService.get<string>('BILLING_PLAN_REQUIRED_LINK') ?? '';
}
getBillingStripeBasePlanProductId(): string {
get<T extends keyof EnvironmentVariables>(key: T): EnvironmentVariables[T] {
return (
this.configService.get<string>('BILLING_STRIPE_BASE_PLAN_PRODUCT_ID') ??
''
this.configService.get<EnvironmentVariables[T]>(key) ??
EnvironmentDefault[key]
);
}
getBillingStripeApiKey(): string {
return this.configService.get<string>('BILLING_STRIPE_API_KEY') ?? '';
}
getBillingStripeWebhookSecret(): string {
return (
this.configService.get<string>('BILLING_STRIPE_WEBHOOK_SECRET') ?? ''
);
}
getBillingFreeTrialDurationInDays(): number {
return (
this.configService.get<number>('BILLING_FREE_TRIAL_DURATION_IN_DAYS') ?? 7
);
}
isTelemetryEnabled(): boolean {
return this.configService.get<boolean>('TELEMETRY_ENABLED') ?? true;
}
isTelemetryAnonymizationEnabled(): boolean {
return (
this.configService.get<boolean>('TELEMETRY_ANONYMIZATION_ENABLED') ?? true
);
}
getPort(): number {
return this.configService.get<number>('PORT') ?? 3000;
}
getPGDatabaseUrl(): string {
return this.configService.get<string>('PG_DATABASE_URL')!;
}
getRedisHost(): string {
return this.configService.get<string>('REDIS_HOST') ?? '127.0.0.1';
}
getRedisPort(): number {
return +(this.configService.get<string>('REDIS_PORT') ?? 6379);
}
getFrontBaseUrl(): string {
return this.configService.get<string>('FRONT_BASE_URL')!;
}
getServerUrl(): string {
const url = this.configService.get<string>('SERVER_URL')!;
@ -103,262 +34,15 @@ export class EnvironmentService {
);
}
getAccessTokenSecret(): string {
return this.configService.get<string>('ACCESS_TOKEN_SECRET')!;
}
getAccessTokenExpiresIn(): string {
return this.configService.get<string>('ACCESS_TOKEN_EXPIRES_IN') ?? '30m';
}
getRefreshTokenSecret(): string {
return this.configService.get<string>('REFRESH_TOKEN_SECRET')!;
}
getRefreshTokenExpiresIn(): string {
return this.configService.get<string>('REFRESH_TOKEN_EXPIRES_IN') ?? '90d';
}
getRefreshTokenCoolDown(): string {
return this.configService.get<string>('REFRESH_TOKEN_COOL_DOWN') ?? '1m';
}
getLoginTokenSecret(): string {
return this.configService.get<string>('LOGIN_TOKEN_SECRET')!;
}
getLoginTokenExpiresIn(): string {
return this.configService.get<string>('LOGIN_TOKEN_EXPIRES_IN') ?? '15m';
}
getTransientTokenExpiresIn(): string {
return (
this.configService.get<string>('SHORT_TERM_TOKEN_EXPIRES_IN') ?? '5m'
);
}
getApiTokenExpiresIn(): string {
return this.configService.get<string>('API_TOKEN_EXPIRES_IN') ?? '1000y';
}
getFrontAuthCallbackUrl(): string {
return (
this.configService.get<string>('FRONT_AUTH_CALLBACK_URL') ??
this.getFrontBaseUrl() + '/verify'
);
}
isMessagingProviderGmailEnabled(): boolean {
return (
this.configService.get<boolean>('MESSAGING_PROVIDER_GMAIL_ENABLED') ??
false
);
}
isCalendarProviderGoogleEnabled(): boolean {
return (
this.configService.get<boolean>('CALENDAR_PROVIDER_GOOGLE_ENABLED') ??
false
);
}
getMessagingProviderGmailCallbackUrl(): string | undefined {
return this.configService.get<string>(
'MESSAGING_PROVIDER_GMAIL_CALLBACK_URL',
);
}
getAuthGoogleAPIsCallbackUrl(): string | undefined {
return this.configService.get<string>('AUTH_GOOGLE_APIS_CALLBACK_URL');
}
isAuthGoogleEnabled(): boolean {
return this.configService.get<boolean>('AUTH_GOOGLE_ENABLED') ?? false;
}
getAuthGoogleClientId(): string | undefined {
return this.configService.get<string>('AUTH_GOOGLE_CLIENT_ID');
}
getAuthGoogleClientSecret(): string | undefined {
return this.configService.get<string>('AUTH_GOOGLE_CLIENT_SECRET');
}
getAuthGoogleCallbackUrl(): string | undefined {
return this.configService.get<string>('AUTH_GOOGLE_CALLBACK_URL');
}
getStorageDriverType(): StorageDriverType {
return (
this.configService.get<StorageDriverType>('STORAGE_TYPE') ??
StorageDriverType.Local
);
}
getMessageQueueDriverType(): MessageQueueDriverType {
return (
this.configService.get<MessageQueueDriverType>('MESSAGE_QUEUE_TYPE') ??
MessageQueueDriverType.Sync
);
}
getStorageS3Region(): AwsRegion | undefined {
return this.configService.get<AwsRegion>('STORAGE_S3_REGION');
}
getStorageS3Name(): string | undefined {
return this.configService.get<string>('STORAGE_S3_NAME');
}
getStorageS3Endpoint(): string | undefined {
return this.configService.get<string>('STORAGE_S3_ENDPOINT');
}
getStorageLocalPath(): string {
return (
this.configService.get<string>('STORAGE_LOCAL_PATH') ?? '.local-storage'
);
}
getEmailFromAddress(): string {
return (
this.configService.get<string>('EMAIL_FROM_ADDRESS') ??
'noreply@yourdomain.com'
);
}
getEmailSystemAddress(): string {
return (
this.configService.get<string>('EMAIL_SYSTEM_ADDRESS') ??
'system@yourdomain.com'
);
}
getEmailFromName(): string {
return (
this.configService.get<string>('EMAIL_FROM_NAME') ??
'John from YourDomain'
);
}
getEmailDriver(): EmailDriver {
return (
this.configService.get<EmailDriver>('EMAIL_DRIVER') ?? EmailDriver.Logger
);
}
getEmailHost(): string | undefined {
return this.configService.get<string>('EMAIL_SMTP_HOST');
}
getEmailPort(): number | undefined {
return this.configService.get<number>('EMAIL_SMTP_PORT');
}
getEmailUser(): string | undefined {
return this.configService.get<string>('EMAIL_SMTP_USER');
}
getEmailPassword(): string | undefined {
return this.configService.get<string>('EMAIL_SMTP_PASSWORD');
}
getSupportDriver(): string {
return (
this.configService.get<string>('SUPPORT_DRIVER') ?? SupportDriver.None
);
}
getSupportFrontChatId(): string | undefined {
return this.configService.get<string>('SUPPORT_FRONT_CHAT_ID');
}
getSupportFrontHMACKey(): string | undefined {
return this.configService.get<string>('SUPPORT_FRONT_HMAC_KEY');
}
getLoggerDriverType(): LoggerDriverType {
return (
this.configService.get<LoggerDriverType>('LOGGER_DRIVER') ??
LoggerDriverType.Console
this.get('FRONT_BASE_URL') + '/verify'
);
}
// TODO: check because it isn't called
getLoggerIsBufferEnabled(): boolean | undefined {
return this.configService.get<boolean>('LOGGER_IS_BUFFER_ENABLED') ?? true;
}
getExceptionHandlerDriverType(): ExceptionHandlerDriver {
return (
this.configService.get<ExceptionHandlerDriver>(
'EXCEPTION_HANDLER_DRIVER',
) ?? ExceptionHandlerDriver.Console
);
}
getLogLevels(): LogLevel[] {
return (
this.configService.get<LogLevel[]>('LOG_LEVELS') ?? [
'log',
'error',
'warn',
]
);
}
getSentryDSN(): string | undefined {
return this.configService.get<string | undefined>('SENTRY_DSN');
}
getDemoWorkspaceIds(): string[] {
return this.configService.get<string[]>('DEMO_WORKSPACE_IDS') ?? [];
}
getOpenRouterApiKey(): string | undefined {
return this.configService.get<string | undefined>('OPENROUTER_API_KEY');
}
getPasswordResetTokenExpiresIn(): string {
return (
this.configService.get<string>('PASSWORD_RESET_TOKEN_EXPIRES_IN') ?? '5m'
);
}
getInactiveDaysBeforeEmail(): number | undefined {
return this.configService.get<number | undefined>(
'WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION',
);
}
getInactiveDaysBeforeDelete(): number | undefined {
return this.configService.get<number | undefined>(
'WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION',
);
}
isSignUpDisabled(): boolean {
return this.configService.get<boolean>('IS_SIGN_UP_DISABLED') ?? false;
}
getApiRateLimitingTtl(): number {
return this.configService.get<number>('API_RATE_LIMITING_TTL') ?? 100;
}
getApiRateLimitingLimit(): number {
return this.configService.get<number>('API_RATE_LIMITING_LIMIT') ?? 500;
}
getMutationMaximumRecordAffected(): number {
return (
this.configService.get<number>('MUTATION_MAXIMUM_RECORD_AFFECTED') ?? 100
);
}
getCacheStorageType(): string {
return this.configService.get<string>('CACHE_STORAGE_TYPE') ?? 'memory';
}
getCacheStorageTtl(): number {
return this.configService.get<number>('CACHE_STORAGE_TTL') ?? 3600 * 24 * 7;
}
}

View File

@ -13,7 +13,7 @@ export const exceptionHandlerModuleFactory = async (
environmentService: EnvironmentService,
adapterHost: HttpAdapterHost,
): Promise<typeof OPTIONS_TYPE> => {
const driverType = environmentService.getExceptionHandlerDriverType();
const driverType = environmentService.get('EXCEPTION_HANDLER_DRIVER');
switch (driverType) {
case ExceptionHandlerDriver.Console: {
@ -25,9 +25,9 @@ export const exceptionHandlerModuleFactory = async (
return {
type: ExceptionHandlerDriver.Sentry,
options: {
dsn: environmentService.getSentryDSN() ?? '',
dsn: environmentService.get('SENTRY_DSN') ?? '',
serverInstance: adapterHost.httpAdapter?.getInstance(),
debug: environmentService.isDebugMode(),
debug: environmentService.get('DEBUG_MODE'),
},
};
}

View File

@ -14,11 +14,11 @@ import {
export const fileStorageModuleFactory = async (
environmentService: EnvironmentService,
): Promise<FileStorageModuleOptions> => {
const driverType = environmentService.getStorageDriverType();
const driverType = environmentService.get('STORAGE_TYPE');
switch (driverType) {
case StorageDriverType.Local: {
const storagePath = environmentService.getStorageLocalPath();
const storagePath = environmentService.get('STORAGE_LOCAL_PATH');
return {
type: StorageDriverType.Local,
@ -28,9 +28,9 @@ export const fileStorageModuleFactory = async (
};
}
case StorageDriverType.S3: {
const bucketName = environmentService.getStorageS3Name();
const endpoint = environmentService.getStorageS3Endpoint();
const region = environmentService.getStorageS3Region();
const bucketName = environmentService.get('STORAGE_S3_NAME');
const endpoint = environmentService.get('STORAGE_S3_ENDPOINT');
const region = environmentService.get('STORAGE_S3_REGION');
return {
type: StorageDriverType.S3,

View File

@ -12,8 +12,8 @@ import {
export const loggerModuleFactory = async (
environmentService: EnvironmentService,
): Promise<LoggerModuleOptions> => {
const driverType = environmentService.getLoggerDriverType();
const logLevels = environmentService.getLogLevels();
const driverType = environmentService.get('LOGGER_DRIVER');
const logLevels = environmentService.get('LOG_LEVELS');
switch (driverType) {
case LoggerDriverType.Console: {

View File

@ -12,7 +12,7 @@ import {
export const messageQueueModuleFactory = async (
environmentService: EnvironmentService,
): Promise<MessageQueueModuleOptions> => {
const driverType = environmentService.getMessageQueueDriverType();
const driverType = environmentService.get('MESSAGE_QUEUE_TYPE');
switch (driverType) {
case MessageQueueDriverType.Sync: {
@ -22,7 +22,7 @@ export const messageQueueModuleFactory = async (
};
}
case MessageQueueDriverType.PgBoss: {
const connectionString = environmentService.getPGDatabaseUrl();
const connectionString = environmentService.get('PG_DATABASE_URL');
return {
type: MessageQueueDriverType.PgBoss,
@ -32,8 +32,8 @@ export const messageQueueModuleFactory = async (
};
}
case MessageQueueDriverType.BullMQ: {
const host = environmentService.getRedisHost();
const port = environmentService.getRedisPort();
const host = environmentService.get('REDIS_HOST');
const port = environmentService.get('REDIS_PORT');
return {
type: MessageQueueDriverType.BullMQ,

View File

@ -53,7 +53,7 @@ const bootstrap = async () => {
}),
);
await app.listen(app.get(EnvironmentService).getPort());
await app.listen(app.get(EnvironmentService).get('PORT'));
};
bootstrap();

View File

@ -26,8 +26,8 @@ export const metadataModuleFactory = async (
resolvers: { JSON: GraphQLJSON },
plugins: [
useThrottler({
ttl: environmentService.getApiRateLimitingTtl(),
limit: environmentService.getApiRateLimitingLimit(),
ttl: environmentService.get('API_RATE_LIMITING_TTL'),
limit: environmentService.get('API_RATE_LIMITING_LIMIT'),
identifyFn: (context) => {
return context.user?.id ?? context.req.ip ?? 'anonymous';
},
@ -39,7 +39,7 @@ export const metadataModuleFactory = async (
path: '/metadata',
};
if (environmentService.isDebugMode()) {
if (environmentService.get('DEBUG_MODE')) {
config.renderGraphiQL = () => {
return renderApolloPlayground({ path: 'metadata' });
};

View File

@ -48,8 +48,8 @@ export class GoogleAPIsRefreshAccessTokenService {
const response = await axios.post(
'https://oauth2.googleapis.com/token',
{
client_id: this.environmentService.getAuthGoogleClientId(),
client_secret: this.environmentService.getAuthGoogleClientSecret(),
client_id: this.environmentService.get('AUTH_GOOGLE_CLIENT_ID'),
client_secret: this.environmentService.get('AUTH_GOOGLE_CLIENT_SECRET'),
refresh_token: refreshToken,
grant_type: 'refresh_token',
},

View File

@ -23,10 +23,12 @@ export class GoogleCalendarClientProvider {
}
private async getOAuth2Client(refreshToken: string): Promise<OAuth2Client> {
const googleCalendarClientId =
this.environmentService.getAuthGoogleClientId();
const googleCalendarClientSecret =
this.environmentService.getAuthGoogleClientSecret();
const googleCalendarClientId = this.environmentService.get(
'AUTH_GOOGLE_CLIENT_ID',
);
const googleCalendarClientSecret = this.environmentService.get(
'AUTH_GOOGLE_CLIENT_SECRET',
);
const oAuth2Client = new google.auth.OAuth2(
googleCalendarClientId,

View File

@ -21,9 +21,9 @@ export class GmailClientProvider {
}
private async getOAuth2Client(refreshToken: string): Promise<OAuth2Client> {
const gmailClientId = this.environmentService.getAuthGoogleClientId();
const gmailClientId = this.environmentService.get('AUTH_GOOGLE_CLIENT_ID');
const gmailClientSecret =
this.environmentService.getAuthGoogleClientSecret();
this.environmentService.get('AUTH_GOOGLE_CLIENT_SECRET');
const oAuth2Client = new google.auth.OAuth2(
gmailClientId,

View File

@ -45,9 +45,9 @@ export class CleanInactiveWorkspaceJob
private readonly environmentService: EnvironmentService,
) {
this.inactiveDaysBeforeDelete =
this.environmentService.getInactiveDaysBeforeDelete();
this.environmentService.get('WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION');
this.inactiveDaysBeforeEmail =
this.environmentService.getInactiveDaysBeforeEmail();
this.environmentService.get('WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION');
}
async getMostRecentUpdatedAt(
@ -133,8 +133,8 @@ export class CleanInactiveWorkspaceJob
this.emailService.send({
to: workspaceMember.email,
bcc: this.environmentService.getEmailSystemAddress(),
from: `${this.environmentService.getEmailFromName()} <${this.environmentService.getEmailFromAddress()}>`,
bcc: this.environmentService.get('EMAIL_SYSTEM_ADDRESS'),
from: `${this.environmentService.get('EMAIL_FROM_NAME')} <${this.environmentService.get('EMAIL_FROM_ADDRESS')}>`,
subject: 'Action Needed to Prevent Workspace Deletion',
html,
text,
@ -179,8 +179,8 @@ export class CleanInactiveWorkspaceJob
});
await this.emailService.send({
to: this.environmentService.getEmailSystemAddress(),
from: `${this.environmentService.getEmailFromName()} <${this.environmentService.getEmailFromAddress()}>`,
to: this.environmentService.get('EMAIL_SYSTEM_ADDRESS'),
from: `${this.environmentService.get('EMAIL_FROM_NAME')} <${this.environmentService.get('EMAIL_FROM_ADDRESS')}>`,
subject: 'Action Needed to Delete Workspaces',
html,
text,

View File

@ -307,7 +307,7 @@ export class WorkspaceQueryRunnerService {
): Promise<Record[] | undefined> {
const { workspaceId, objectMetadataItem } = options;
const maximumRecordAffected =
this.environmentService.getMutationMaximumRecordAffected();
this.environmentService.get('MUTATION_MAXIMUM_RECORD_AFFECTED');
const query = await this.workspaceQueryBuilderFactory.updateMany(args, {
...options,
atMost: maximumRecordAffected,
@ -339,7 +339,7 @@ export class WorkspaceQueryRunnerService {
): Promise<Record[] | undefined> {
const { workspaceId, objectMetadataItem } = options;
const maximumRecordAffected =
this.environmentService.getMutationMaximumRecordAffected();
this.environmentService.get('MUTATION_MAXIMUM_RECORD_AFFECTED');
const query = await this.workspaceQueryBuilderFactory.deleteMany(args, {
...options,
atMost: maximumRecordAffected,