Refacto environment service (#4473)
* Refacto environment service * Remove environment variable type
This commit is contained in:
@ -23,12 +23,13 @@ export class AnalyticsService {
|
|||||||
workspace: Workspace | undefined,
|
workspace: Workspace | undefined,
|
||||||
request: Request,
|
request: Request,
|
||||||
) {
|
) {
|
||||||
if (!this.environmentService.isTelemetryEnabled()) {
|
if (!this.environmentService.get('TELEMETRY_ENABLED')) {
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
const anonymizationEnabled =
|
const anonymizationEnabled = this.environmentService.get(
|
||||||
this.environmentService.isTelemetryAnonymizationEnabled();
|
'TELEMETRY_ANONYMIZATION_ENABLED',
|
||||||
|
);
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
type: createEventInput.type,
|
type: createEventInput.type,
|
||||||
|
|||||||
@ -47,7 +47,7 @@ export class ApiRestQueryBuilderFactory {
|
|||||||
|
|
||||||
if (!objectMetadataItems.length) {
|
if (!objectMetadataItems.length) {
|
||||||
throw new BadRequestException(
|
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`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,9 +30,9 @@ import { AuthService } from './services/auth.service';
|
|||||||
const jwtModule = JwtModule.registerAsync({
|
const jwtModule = JwtModule.registerAsync({
|
||||||
useFactory: async (environmentService: EnvironmentService) => {
|
useFactory: async (environmentService: EnvironmentService) => {
|
||||||
return {
|
return {
|
||||||
secret: environmentService.getAccessTokenSecret(),
|
secret: environmentService.get('ACCESS_TOKEN_SECRET'),
|
||||||
signOptions: {
|
signOptions: {
|
||||||
expiresIn: environmentService.getAccessTokenExpiresIn(),
|
expiresIn: environmentService.get('ACCESS_TOKEN_EXPIRES_IN'),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -37,7 +37,7 @@ export class GoogleAPIsAuthController {
|
|||||||
const { workspaceMemberId, workspaceId } =
|
const { workspaceMemberId, workspaceId } =
|
||||||
await this.tokenService.verifyTransientToken(transientToken);
|
await this.tokenService.verifyTransientToken(transientToken);
|
||||||
|
|
||||||
const demoWorkspaceIds = this.environmentService.getDemoWorkspaceIds();
|
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
|
||||||
|
|
||||||
if (demoWorkspaceIds.includes(workspaceId)) {
|
if (demoWorkspaceIds.includes(workspaceId)) {
|
||||||
throw new Error('Cannot connect Google account to demo workspace');
|
throw new Error('Cannot connect Google account to demo workspace');
|
||||||
@ -57,7 +57,7 @@ export class GoogleAPIsAuthController {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return res.redirect(
|
return res.redirect(
|
||||||
`${this.environmentService.getFrontBaseUrl()}/settings/accounts`,
|
`${this.environmentService.get('FRONT_BASE_URL')}/settings/accounts`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@ export class GoogleGmailAuthController {
|
|||||||
const { workspaceMemberId, workspaceId } =
|
const { workspaceMemberId, workspaceId } =
|
||||||
await this.tokenService.verifyTransientToken(transientToken);
|
await this.tokenService.verifyTransientToken(transientToken);
|
||||||
|
|
||||||
const demoWorkspaceIds = this.environmentService.getDemoWorkspaceIds();
|
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
|
||||||
|
|
||||||
if (demoWorkspaceIds.includes(workspaceId)) {
|
if (demoWorkspaceIds.includes(workspaceId)) {
|
||||||
throw new Error('Cannot connect Gmail account to demo workspace');
|
throw new Error('Cannot connect Gmail account to demo workspace');
|
||||||
@ -58,7 +58,7 @@ export class GoogleGmailAuthController {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return res.redirect(
|
return res.redirect(
|
||||||
`${this.environmentService.getFrontBaseUrl()}/settings/accounts`,
|
`${this.environmentService.get('FRONT_BASE_URL')}/settings/accounts`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,8 +11,8 @@ export class GoogleAPIsProviderEnabledGuard implements CanActivate {
|
|||||||
|
|
||||||
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
|
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
|
||||||
if (
|
if (
|
||||||
!this.environmentService.isMessagingProviderGmailEnabled() &&
|
!this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED') &&
|
||||||
!this.environmentService.isCalendarProviderGoogleEnabled()
|
!this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
|
||||||
) {
|
) {
|
||||||
throw new NotFoundException('Google apis auth is not enabled');
|
throw new NotFoundException('Google apis auth is not enabled');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,7 +10,7 @@ export class GoogleProviderEnabledGuard implements CanActivate {
|
|||||||
constructor(private readonly environmentService: EnvironmentService) {}
|
constructor(private readonly environmentService: EnvironmentService) {}
|
||||||
|
|
||||||
canActivate(): boolean | Promise<boolean> | Observable<boolean> {
|
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');
|
throw new NotFoundException('Google auth is not enabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -194,7 +194,7 @@ export class AuthService {
|
|||||||
const emailTemplate = PasswordUpdateNotifyEmail({
|
const emailTemplate = PasswordUpdateNotifyEmail({
|
||||||
userName: `${user.firstName} ${user.lastName}`,
|
userName: `${user.firstName} ${user.lastName}`,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
link: this.environmentService.getFrontBaseUrl(),
|
link: this.environmentService.get('FRONT_BASE_URL'),
|
||||||
});
|
});
|
||||||
|
|
||||||
const html = render(emailTemplate, {
|
const html = render(emailTemplate, {
|
||||||
@ -205,7 +205,7 @@ export class AuthService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.emailService.send({
|
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,
|
to: user.email,
|
||||||
subject: 'Your Password Has Been Successfully Changed',
|
subject: 'Your Password Has Been Successfully Changed',
|
||||||
text,
|
text,
|
||||||
|
|||||||
@ -88,7 +88,7 @@ export class GoogleAPIsService {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this.environmentService.isMessagingProviderGmailEnabled()) {
|
if (this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED')) {
|
||||||
await manager.query(
|
await manager.query(
|
||||||
`INSERT INTO ${dataSourceMetadata.schema}."messageChannel" ("visibility", "handle", "connectedAccountId", "type") VALUES ($1, $2, $3, $4)`,
|
`INSERT INTO ${dataSourceMetadata.schema}."messageChannel" ("visibility", "handle", "connectedAccountId", "type") VALUES ($1, $2, $3, $4)`,
|
||||||
['share_everything', handle, connectedAccountId, 'email'],
|
['share_everything', handle, connectedAccountId, 'email'],
|
||||||
@ -96,7 +96,7 @@ export class GoogleAPIsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.environmentService.isCalendarProviderGoogleEnabled() &&
|
this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED') &&
|
||||||
IsCalendarEnabled
|
IsCalendarEnabled
|
||||||
) {
|
) {
|
||||||
await manager.query(
|
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>(
|
await this.messageQueueService.add<GmailFullSyncJobData>(
|
||||||
GmailFullSyncJob.name,
|
GmailFullSyncJob.name,
|
||||||
{
|
{
|
||||||
@ -120,7 +120,7 @@ export class GoogleAPIsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.environmentService.isCalendarProviderGoogleEnabled() &&
|
this.environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED') &&
|
||||||
IsCalendarEnabled
|
IsCalendarEnabled
|
||||||
) {
|
) {
|
||||||
await this.calendarQueueService.add<GoogleCalendarFullSyncJobData>(
|
await this.calendarQueueService.add<GoogleCalendarFullSyncJobData>(
|
||||||
|
|||||||
@ -190,7 +190,7 @@ export class SignUpService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
!this.environmentService.isSignUpDisabled(),
|
!this.environmentService.get('IS_SIGN_UP_DISABLED'),
|
||||||
'Sign up is disabled',
|
'Sign up is disabled',
|
||||||
ForbiddenException,
|
ForbiddenException,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -63,7 +63,7 @@ export class TokenService {
|
|||||||
userId: string,
|
userId: string,
|
||||||
workspaceId?: string,
|
workspaceId?: string,
|
||||||
): Promise<AuthToken> {
|
): Promise<AuthToken> {
|
||||||
const expiresIn = this.environmentService.getAccessTokenExpiresIn();
|
const expiresIn = this.environmentService.get('ACCESS_TOKEN_EXPIRES_IN');
|
||||||
|
|
||||||
assert(expiresIn, '', InternalServerErrorException);
|
assert(expiresIn, '', InternalServerErrorException);
|
||||||
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
|
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
|
||||||
@ -93,8 +93,8 @@ export class TokenService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async generateRefreshToken(userId: string): Promise<AuthToken> {
|
async generateRefreshToken(userId: string): Promise<AuthToken> {
|
||||||
const secret = this.environmentService.getRefreshTokenSecret();
|
const secret = this.environmentService.get('REFRESH_TOKEN_SECRET');
|
||||||
const expiresIn = this.environmentService.getRefreshTokenExpiresIn();
|
const expiresIn = this.environmentService.get('REFRESH_TOKEN_EXPIRES_IN');
|
||||||
|
|
||||||
assert(expiresIn, '', InternalServerErrorException);
|
assert(expiresIn, '', InternalServerErrorException);
|
||||||
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
|
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
|
||||||
@ -124,8 +124,8 @@ export class TokenService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async generateLoginToken(email: string): Promise<AuthToken> {
|
async generateLoginToken(email: string): Promise<AuthToken> {
|
||||||
const secret = this.environmentService.getLoginTokenSecret();
|
const secret = this.environmentService.get('LOGIN_TOKEN_SECRET');
|
||||||
const expiresIn = this.environmentService.getLoginTokenExpiresIn();
|
const expiresIn = this.environmentService.get('LOGIN_TOKEN_EXPIRES_IN');
|
||||||
|
|
||||||
assert(expiresIn, '', InternalServerErrorException);
|
assert(expiresIn, '', InternalServerErrorException);
|
||||||
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
|
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
|
||||||
@ -146,8 +146,8 @@ export class TokenService {
|
|||||||
workspaceMemberId: string,
|
workspaceMemberId: string,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
): Promise<AuthToken> {
|
): Promise<AuthToken> {
|
||||||
const secret = this.environmentService.getLoginTokenSecret();
|
const secret = this.environmentService.get('LOGIN_TOKEN_SECRET');
|
||||||
const expiresIn = this.environmentService.getTransientTokenExpiresIn();
|
const expiresIn = this.environmentService.get('SHORT_TERM_TOKEN_EXPIRES_IN');
|
||||||
|
|
||||||
assert(expiresIn, '', InternalServerErrorException);
|
assert(expiresIn, '', InternalServerErrorException);
|
||||||
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
|
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
|
||||||
@ -176,7 +176,7 @@ export class TokenService {
|
|||||||
const jwtPayload = {
|
const jwtPayload = {
|
||||||
sub: workspaceId,
|
sub: workspaceId,
|
||||||
};
|
};
|
||||||
const secret = this.environmentService.getAccessTokenSecret();
|
const secret = this.environmentService.get('ACCESS_TOKEN_SECRET');
|
||||||
let expiresIn: string | number;
|
let expiresIn: string | number;
|
||||||
|
|
||||||
if (expiresAt) {
|
if (expiresAt) {
|
||||||
@ -184,7 +184,7 @@ export class TokenService {
|
|||||||
(new Date(expiresAt).getTime() - new Date().getTime()) / 1000,
|
(new Date(expiresAt).getTime() - new Date().getTime()) / 1000,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
expiresIn = this.environmentService.getApiTokenExpiresIn();
|
expiresIn = this.environmentService.get('API_TOKEN_EXPIRES_IN');
|
||||||
}
|
}
|
||||||
const token = this.jwtService.sign(jwtPayload, {
|
const token = this.jwtService.sign(jwtPayload, {
|
||||||
secret,
|
secret,
|
||||||
@ -209,7 +209,7 @@ export class TokenService {
|
|||||||
}
|
}
|
||||||
const decoded = await this.verifyJwt(
|
const decoded = await this.verifyJwt(
|
||||||
token,
|
token,
|
||||||
this.environmentService.getAccessTokenSecret(),
|
this.environmentService.get('ACCESS_TOKEN_SECRET'),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { user, workspace } = await this.jwtStrategy.validate(
|
const { user, workspace } = await this.jwtStrategy.validate(
|
||||||
@ -220,7 +220,7 @@ export class TokenService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async verifyLoginToken(loginToken: string): Promise<string> {
|
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);
|
const payload = await this.verifyJwt(loginToken, loginTokenSecret);
|
||||||
|
|
||||||
@ -231,7 +231,7 @@ export class TokenService {
|
|||||||
workspaceMemberId: string;
|
workspaceMemberId: string;
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
}> {
|
}> {
|
||||||
const transientTokenSecret = this.environmentService.getLoginTokenSecret();
|
const transientTokenSecret = this.environmentService.get('LOGIN_TOKEN_SECRET');
|
||||||
|
|
||||||
const payload = await this.verifyJwt(transientToken, transientTokenSecret);
|
const payload = await this.verifyJwt(transientToken, transientTokenSecret);
|
||||||
|
|
||||||
@ -281,8 +281,8 @@ export class TokenService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async verifyRefreshToken(refreshToken: string) {
|
async verifyRefreshToken(refreshToken: string) {
|
||||||
const secret = this.environmentService.getRefreshTokenSecret();
|
const secret = this.environmentService.get('REFRESH_TOKEN_SECRET');
|
||||||
const coolDown = this.environmentService.getRefreshTokenCoolDown();
|
const coolDown = this.environmentService.get('REFRESH_TOKEN_COOL_DOWN');
|
||||||
const jwtPayload = await this.verifyJwt(refreshToken, secret);
|
const jwtPayload = await this.verifyJwt(refreshToken, secret);
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
@ -382,7 +382,7 @@ export class TokenService {
|
|||||||
|
|
||||||
assert(user, 'User not found', NotFoundException);
|
assert(user, 'User not found', NotFoundException);
|
||||||
|
|
||||||
const expiresIn = this.environmentService.getPasswordResetTokenExpiresIn();
|
const expiresIn = this.environmentService.get('PASSWORD_RESET_TOKEN_EXPIRES_IN');
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
expiresIn,
|
expiresIn,
|
||||||
@ -439,7 +439,7 @@ export class TokenService {
|
|||||||
|
|
||||||
assert(user, 'User not found', NotFoundException);
|
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 resetLink = `${frontBaseURL}/reset-password/${resetToken.passwordResetToken}`;
|
||||||
|
|
||||||
const emailData = {
|
const emailData = {
|
||||||
@ -465,7 +465,7 @@ export class TokenService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.emailService.send({
|
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,
|
to: email,
|
||||||
subject: 'Action Needed to Reset Password',
|
subject: 'Action Needed to Reset Password',
|
||||||
text,
|
text,
|
||||||
|
|||||||
@ -27,20 +27,20 @@ export class GoogleAPIsStrategy extends PassportStrategy(
|
|||||||
constructor(environmentService: EnvironmentService) {
|
constructor(environmentService: EnvironmentService) {
|
||||||
const scope = ['email', 'profile'];
|
const scope = ['email', 'profile'];
|
||||||
|
|
||||||
if (environmentService.isMessagingProviderGmailEnabled()) {
|
if (environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED')) {
|
||||||
scope.push('https://www.googleapis.com/auth/gmail.readonly');
|
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');
|
scope.push('https://www.googleapis.com/auth/calendar');
|
||||||
}
|
}
|
||||||
|
|
||||||
super({
|
super({
|
||||||
clientID: environmentService.getAuthGoogleClientId(),
|
clientID: environmentService.get('AUTH_GOOGLE_CLIENT_ID'),
|
||||||
clientSecret: environmentService.getAuthGoogleClientSecret(),
|
clientSecret: environmentService.get('AUTH_GOOGLE_CLIENT_SECRET'),
|
||||||
callbackURL: environmentService.isCalendarProviderGoogleEnabled()
|
callbackURL: environmentService.get('CALENDAR_PROVIDER_GOOGLE_ENABLED')
|
||||||
? environmentService.getAuthGoogleAPIsCallbackUrl()
|
? environmentService.get('AUTH_GOOGLE_APIS_CALLBACK_URL')
|
||||||
: environmentService.getMessagingProviderGmailCallbackUrl(),
|
: environmentService.get('MESSAGING_PROVIDER_GMAIL_CALLBACK_URL'),
|
||||||
scope,
|
scope,
|
||||||
passReqToCallback: true,
|
passReqToCallback: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -20,9 +20,9 @@ export type GoogleRequest = Request & {
|
|||||||
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
|
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
|
||||||
constructor(environmentService: EnvironmentService) {
|
constructor(environmentService: EnvironmentService) {
|
||||||
super({
|
super({
|
||||||
clientID: environmentService.getAuthGoogleClientId(),
|
clientID: environmentService.get('AUTH_GOOGLE_CLIENT_ID'),
|
||||||
clientSecret: environmentService.getAuthGoogleClientSecret(),
|
clientSecret: environmentService.get('AUTH_GOOGLE_CLIENT_SECRET'),
|
||||||
callbackURL: environmentService.getAuthGoogleCallbackUrl(),
|
callbackURL: environmentService.get('AUTH_GOOGLE_CALLBACK_URL'),
|
||||||
scope: ['email', 'profile'],
|
scope: ['email', 'profile'],
|
||||||
passReqToCallback: true,
|
passReqToCallback: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -33,7 +33,7 @@ export class JwtAuthStrategy extends PassportStrategy(Strategy, 'jwt') {
|
|||||||
super({
|
super({
|
||||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||||
ignoreExpiration: false,
|
ignoreExpiration: false,
|
||||||
secretOrKey: environmentService.getAccessTokenSecret(),
|
secretOrKey: environmentService.get('ACCESS_TOKEN_SECRET'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,7 @@ export class BillingService {
|
|||||||
|
|
||||||
getProductStripeId(product: AvailableProduct) {
|
getProductStripeId(product: AvailableProduct) {
|
||||||
if (product === AvailableProduct.BasePlan) {
|
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(
|
async getBillingSubscriptionItem(
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
stripeProductId = this.environmentService.getBillingStripeBasePlanProductId(),
|
stripeProductId = this.environmentService.get('BILLING_STRIPE_BASE_PLAN_PRODUCT_ID'),
|
||||||
) {
|
) {
|
||||||
const billingSubscription = await this.getCurrentBillingSubscription({
|
const billingSubscription = await this.getCurrentBillingSubscription({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@ -134,7 +134,7 @@ export class BillingService {
|
|||||||
where: { workspaceId },
|
where: { workspaceId },
|
||||||
});
|
});
|
||||||
|
|
||||||
const frontBaseUrl = this.environmentService.getFrontBaseUrl();
|
const frontBaseUrl = this.environmentService.get('FRONT_BASE_URL');
|
||||||
const returnUrl = returnUrlPath
|
const returnUrl = returnUrlPath
|
||||||
? frontBaseUrl + returnUrlPath
|
? frontBaseUrl + returnUrlPath
|
||||||
: frontBaseUrl;
|
: frontBaseUrl;
|
||||||
@ -154,7 +154,7 @@ export class BillingService {
|
|||||||
priceId: string,
|
priceId: string,
|
||||||
successUrlPath?: string,
|
successUrlPath?: string,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const frontBaseUrl = this.environmentService.getFrontBaseUrl();
|
const frontBaseUrl = this.environmentService.get('FRONT_BASE_URL');
|
||||||
const successUrl = successUrlPath
|
const successUrl = successUrlPath
|
||||||
? frontBaseUrl + successUrlPath
|
? frontBaseUrl + successUrlPath
|
||||||
: frontBaseUrl;
|
: frontBaseUrl;
|
||||||
|
|||||||
@ -12,14 +12,14 @@ export class StripeService {
|
|||||||
|
|
||||||
constructor(private readonly environmentService: EnvironmentService) {
|
constructor(private readonly environmentService: EnvironmentService) {
|
||||||
this.stripe = new Stripe(
|
this.stripe = new Stripe(
|
||||||
this.environmentService.getBillingStripeApiKey(),
|
this.environmentService.get('BILLING_STRIPE_API_KEY'),
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructEventFromPayload(signature: string, payload: Buffer) {
|
constructEventFromPayload(signature: string, payload: Buffer) {
|
||||||
const webhookSecret =
|
const webhookSecret =
|
||||||
this.environmentService.getBillingStripeWebhookSecret();
|
this.environmentService.get('BILLING_STRIPE_WEBHOOK_SECRET');
|
||||||
|
|
||||||
return this.stripe.webhooks.constructEvent(
|
return this.stripe.webhooks.constructEvent(
|
||||||
payload,
|
payload,
|
||||||
@ -48,7 +48,7 @@ export class StripeService {
|
|||||||
): Promise<Stripe.BillingPortal.Session> {
|
): Promise<Stripe.BillingPortal.Session> {
|
||||||
return await this.stripe.billingPortal.sessions.create({
|
return await this.stripe.billingPortal.sessions.create({
|
||||||
customer: stripeCustomerId,
|
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,
|
workspaceId: user.defaultWorkspace.id,
|
||||||
},
|
},
|
||||||
trial_period_days:
|
trial_period_days:
|
||||||
this.environmentService.getBillingFreeTrialDurationInDays(),
|
this.environmentService.get('BILLING_FREE_TRIAL_DURATION_IN_DAYS'),
|
||||||
},
|
},
|
||||||
automatic_tax: { enabled: true },
|
automatic_tax: { enabled: true },
|
||||||
tax_id_collection: { enabled: true },
|
tax_id_collection: { enabled: true },
|
||||||
|
|||||||
@ -12,30 +12,34 @@ export class ClientConfigResolver {
|
|||||||
async clientConfig(): Promise<ClientConfig> {
|
async clientConfig(): Promise<ClientConfig> {
|
||||||
const clientConfig: ClientConfig = {
|
const clientConfig: ClientConfig = {
|
||||||
authProviders: {
|
authProviders: {
|
||||||
google: this.environmentService.isAuthGoogleEnabled(),
|
google: this.environmentService.get('AUTH_GOOGLE_ENABLED'),
|
||||||
magicLink: false,
|
magicLink: false,
|
||||||
password: true,
|
password: true,
|
||||||
},
|
},
|
||||||
telemetry: {
|
telemetry: {
|
||||||
enabled: this.environmentService.isTelemetryEnabled(),
|
enabled: this.environmentService.get('TELEMETRY_ENABLED'),
|
||||||
anonymizationEnabled:
|
anonymizationEnabled: this.environmentService.get(
|
||||||
this.environmentService.isTelemetryAnonymizationEnabled(),
|
'TELEMETRY_ANONYMIZATION_ENABLED',
|
||||||
|
),
|
||||||
},
|
},
|
||||||
billing: {
|
billing: {
|
||||||
isBillingEnabled: this.environmentService.isBillingEnabled(),
|
isBillingEnabled: this.environmentService.get('IS_BILLING_ENABLED'),
|
||||||
billingUrl: this.environmentService.getBillingUrl(),
|
billingUrl: this.environmentService.get('BILLING_PLAN_REQUIRED_LINK'),
|
||||||
billingFreeTrialDurationInDays:
|
billingFreeTrialDurationInDays: this.environmentService.get(
|
||||||
this.environmentService.getBillingFreeTrialDurationInDays(),
|
'BILLING_FREE_TRIAL_DURATION_IN_DAYS',
|
||||||
|
),
|
||||||
},
|
},
|
||||||
signInPrefilled: this.environmentService.isSignInPrefilled(),
|
signInPrefilled: this.environmentService.get('SIGN_IN_PREFILLED'),
|
||||||
signUpDisabled: this.environmentService.isSignUpDisabled(),
|
signUpDisabled: this.environmentService.get('IS_SIGN_UP_DISABLED'),
|
||||||
debugMode: this.environmentService.isDebugMode(),
|
debugMode: this.environmentService.get('DEBUG_MODE'),
|
||||||
support: {
|
support: {
|
||||||
supportDriver: this.environmentService.getSupportDriver(),
|
supportDriver: this.environmentService.get('SUPPORT_DRIVER'),
|
||||||
supportFrontChatId: this.environmentService.getSupportFrontChatId(),
|
supportFrontChatId: this.environmentService.get(
|
||||||
|
'SUPPORT_FRONT_CHAT_ID',
|
||||||
|
),
|
||||||
},
|
},
|
||||||
sentry: {
|
sentry: {
|
||||||
dsn: this.environmentService.getSentryDSN(),
|
dsn: this.environmentService.get('SENTRY_DSN'),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@ export class IntelligenceService {
|
|||||||
'https://openrouter.ai/api/v1/chat/completions',
|
'https://openrouter.ai/api/v1/chat/completions',
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${this.environmentService.getOpenRouterApiKey()}`,
|
Authorization: `Bearer ${this.environmentService.get('OPENROUTER_API_KEY')}`,
|
||||||
'HTTP-Referer': `https://twenty.com`,
|
'HTTP-Referer': `https://twenty.com`,
|
||||||
'X-Title': `Twenty CRM`,
|
'X-Title': `Twenty CRM`,
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|||||||
@ -76,10 +76,10 @@ export class UserResolver {
|
|||||||
nullable: true,
|
nullable: true,
|
||||||
})
|
})
|
||||||
supportUserHash(@Parent() parent: User): string | null {
|
supportUserHash(@Parent() parent: User): string | null {
|
||||||
if (this.environmentService.getSupportDriver() !== SupportDriver.Front) {
|
if (this.environmentService.get('SUPPORT_DRIVER') !== SupportDriver.Front) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const key = this.environmentService.getSupportFrontHMACKey();
|
const key = this.environmentService.get('SUPPORT_FRONT_HMAC_KEY');
|
||||||
|
|
||||||
return getHMACKey(parent.email, key);
|
return getHMACKey(parent.email, key);
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ export class UserResolver {
|
|||||||
@Mutation(() => User)
|
@Mutation(() => User)
|
||||||
async deleteUser(@AuthUser() { id: userId, defaultWorkspace }: User) {
|
async deleteUser(@AuthUser() { id: userId, defaultWorkspace }: User) {
|
||||||
// Get the list of demo workspace IDs
|
// Get the list of demo workspace IDs
|
||||||
const demoWorkspaceIds = this.environmentService.getDemoWorkspaceIds();
|
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
|
||||||
|
|
||||||
const currentUserWorkspaceId = defaultWorkspace.id;
|
const currentUserWorkspaceId = defaultWorkspace.id;
|
||||||
|
|
||||||
|
|||||||
@ -91,7 +91,7 @@ export class WorkspaceResolver {
|
|||||||
|
|
||||||
@Mutation(() => Workspace)
|
@Mutation(() => Workspace)
|
||||||
async deleteCurrentWorkspace(@AuthWorkspace() { id }: 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
|
// Check if the id is in the list of demo workspaceIds
|
||||||
if (demoWorkspaceIds.includes(id)) {
|
if (demoWorkspaceIds.includes(id)) {
|
||||||
|
|||||||
@ -19,14 +19,14 @@ export class DataSeedDemoWorkspaceService {
|
|||||||
async seedDemo(): Promise<void> {
|
async seedDemo(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const dataSource = new DataSource({
|
const dataSource = new DataSource({
|
||||||
url: this.environmentService.getPGDatabaseUrl(),
|
url: this.environmentService.get('PG_DATABASE_URL'),
|
||||||
type: 'postgres',
|
type: 'postgres',
|
||||||
logging: true,
|
logging: true,
|
||||||
schema: 'public',
|
schema: 'public',
|
||||||
});
|
});
|
||||||
|
|
||||||
await dataSource.initialize();
|
await dataSource.initialize();
|
||||||
const demoWorkspaceIds = this.environmentService.getDemoWorkspaceIds();
|
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
|
||||||
|
|
||||||
if (demoWorkspaceIds.length === 0) {
|
if (demoWorkspaceIds.length === 0) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|||||||
@ -38,7 +38,7 @@ export class DataSeedWorkspaceCommand extends CommandRunner {
|
|||||||
async run(): Promise<void> {
|
async run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const dataSource = new DataSource({
|
const dataSource = new DataSource({
|
||||||
url: this.environmentService.getPGDatabaseUrl(),
|
url: this.environmentService.get('PG_DATABASE_URL'),
|
||||||
type: 'postgres',
|
type: 'postgres',
|
||||||
logging: true,
|
logging: true,
|
||||||
schema: 'core',
|
schema: 'core',
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export class TypeORMService implements OnModuleInit, OnModuleDestroy {
|
|||||||
|
|
||||||
constructor(private readonly environmentService: EnvironmentService) {
|
constructor(private readonly environmentService: EnvironmentService) {
|
||||||
this.mainDataSource = new DataSource({
|
this.mainDataSource = new DataSource({
|
||||||
url: environmentService.getPGDatabaseUrl(),
|
url: environmentService.get('PG_DATABASE_URL'),
|
||||||
type: 'postgres',
|
type: 'postgres',
|
||||||
logging: false,
|
logging: false,
|
||||||
schema: 'core',
|
schema: 'core',
|
||||||
@ -83,9 +83,9 @@ export class TypeORMService implements OnModuleInit, OnModuleDestroy {
|
|||||||
const schema = dataSource.schema;
|
const schema = dataSource.schema;
|
||||||
|
|
||||||
const workspaceDataSource = new DataSource({
|
const workspaceDataSource = new DataSource({
|
||||||
url: dataSource.url ?? this.environmentService.getPGDatabaseUrl(),
|
url: dataSource.url ?? this.environmentService.get('PG_DATABASE_URL'),
|
||||||
type: 'postgres',
|
type: 'postgres',
|
||||||
logging: this.environmentService.isDebugMode()
|
logging: this.environmentService.get('DEBUG_MODE')
|
||||||
? ['query', 'error']
|
? ['query', 'error']
|
||||||
: ['error'],
|
: ['error'],
|
||||||
schema,
|
schema,
|
||||||
|
|||||||
@ -46,11 +46,11 @@ export class GraphQLConfigService
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
createGqlOptions(): YogaDriverConfig {
|
createGqlOptions(): YogaDriverConfig {
|
||||||
const isDebugMode = this.environmentService.isDebugMode();
|
const isDebugMode = this.environmentService.get('DEBUG_MODE');
|
||||||
const plugins = [
|
const plugins = [
|
||||||
useThrottler({
|
useThrottler({
|
||||||
ttl: this.environmentService.getApiRateLimitingTtl(),
|
ttl: this.environmentService.get('API_RATE_LIMITING_TTL'),
|
||||||
limit: this.environmentService.getApiRateLimitingLimit(),
|
limit: this.environmentService.get('API_RATE_LIMITING_LIMIT'),
|
||||||
identifyFn: (context) => {
|
identifyFn: (context) => {
|
||||||
return context.user?.id ?? context.req.ip ?? 'anonymous';
|
return context.user?.id ?? context.req.ip ?? 'anonymous';
|
||||||
},
|
},
|
||||||
|
|||||||
@ -8,8 +8,8 @@ import { EnvironmentService } from 'src/integrations/environment/environment.ser
|
|||||||
export const cacheStorageModuleFactory = (
|
export const cacheStorageModuleFactory = (
|
||||||
environmentService: EnvironmentService,
|
environmentService: EnvironmentService,
|
||||||
): CacheModuleOptions => {
|
): CacheModuleOptions => {
|
||||||
const cacheStorageType = environmentService.getCacheStorageType();
|
const cacheStorageType = environmentService.get('CACHE_STORAGE_TYPE');
|
||||||
const cacheStorageTtl = environmentService.getCacheStorageTtl();
|
const cacheStorageTtl = environmentService.get('CACHE_STORAGE_TTL');
|
||||||
const cacheModuleOptions: CacheModuleOptions = {
|
const cacheModuleOptions: CacheModuleOptions = {
|
||||||
isGlobal: true,
|
isGlobal: true,
|
||||||
ttl: cacheStorageTtl * 1000,
|
ttl: cacheStorageTtl * 1000,
|
||||||
@ -20,8 +20,8 @@ export const cacheStorageModuleFactory = (
|
|||||||
return cacheModuleOptions;
|
return cacheModuleOptions;
|
||||||
}
|
}
|
||||||
case CacheStorageType.Redis: {
|
case CacheStorageType.Redis: {
|
||||||
const host = environmentService.getRedisHost();
|
const host = environmentService.get('REDIS_HOST');
|
||||||
const port = environmentService.getRedisPort();
|
const port = environmentService.get('REDIS_PORT');
|
||||||
|
|
||||||
if (!(host && port)) {
|
if (!(host && port)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|||||||
@ -8,17 +8,17 @@ import { EnvironmentService } from 'src/integrations/environment/environment.ser
|
|||||||
export const emailModuleFactory = (
|
export const emailModuleFactory = (
|
||||||
environmentService: EnvironmentService,
|
environmentService: EnvironmentService,
|
||||||
): EmailModuleOptions => {
|
): EmailModuleOptions => {
|
||||||
const driver = environmentService.getEmailDriver();
|
const driver = environmentService.get('EMAIL_DRIVER');
|
||||||
|
|
||||||
switch (driver) {
|
switch (driver) {
|
||||||
case EmailDriver.Logger: {
|
case EmailDriver.Logger: {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case EmailDriver.Smtp: {
|
case EmailDriver.Smtp: {
|
||||||
const host = environmentService.getEmailHost();
|
const host = environmentService.get('EMAIL_SMTP_HOST');
|
||||||
const port = environmentService.getEmailPort();
|
const port = environmentService.get('EMAIL_SMTP_PORT');
|
||||||
const user = environmentService.getEmailUser();
|
const user = environmentService.get('EMAIL_SMTP_USER');
|
||||||
const pass = environmentService.getEmailPassword();
|
const pass = environmentService.get('EMAIL_SMTP_PASSWORD');
|
||||||
|
|
||||||
if (!(host && port)) {
|
if (!(host && port)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|||||||
@ -10,8 +10,11 @@ import {
|
|||||||
validateSync,
|
validateSync,
|
||||||
IsBoolean,
|
IsBoolean,
|
||||||
IsNumber,
|
IsNumber,
|
||||||
|
IsDefined,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
|
||||||
|
import { EmailDriver } from 'src/integrations/email/interfaces/email.interface';
|
||||||
|
|
||||||
import { assert } from 'src/utils/assert';
|
import { assert } from 'src/utils/assert';
|
||||||
import { CastToStringArray } from 'src/integrations/environment/decorators/cast-to-string-array.decorator';
|
import { CastToStringArray } from 'src/integrations/environment/decorators/cast-to-string-array.decorator';
|
||||||
import { ExceptionHandlerDriver } from 'src/integrations/exception-handler/interfaces';
|
import { ExceptionHandlerDriver } from 'src/integrations/exception-handler/interfaces';
|
||||||
@ -32,49 +35,49 @@ export class EnvironmentVariables {
|
|||||||
@CastToBoolean()
|
@CastToBoolean()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
DEBUG_MODE?: boolean;
|
DEBUG_MODE: boolean;
|
||||||
|
|
||||||
@CastToBoolean()
|
@CastToBoolean()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
SIGN_IN_PREFILLED?: boolean;
|
SIGN_IN_PREFILLED: boolean;
|
||||||
|
|
||||||
@CastToBoolean()
|
@CastToBoolean()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
IS_BILLING_ENABLED?: boolean;
|
IS_BILLING_ENABLED: boolean;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
|
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
|
||||||
BILLING_PLAN_REQUIRED_LINK?: string;
|
BILLING_PLAN_REQUIRED_LINK: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
|
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
|
||||||
BILLING_STRIPE_BASE_PLAN_PRODUCT_ID?: string;
|
BILLING_STRIPE_BASE_PLAN_PRODUCT_ID: string;
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@CastToPositiveNumber()
|
@CastToPositiveNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
|
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
|
||||||
BILLING_FREE_TRIAL_DURATION_IN_DAYS?: number;
|
BILLING_FREE_TRIAL_DURATION_IN_DAYS: number;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
|
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
|
||||||
BILLING_STRIPE_API_KEY?: string;
|
BILLING_STRIPE_API_KEY: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
|
@ValidateIf((env) => env.IS_BILLING_ENABLED === true)
|
||||||
BILLING_STRIPE_WEBHOOK_SECRET?: string;
|
BILLING_STRIPE_WEBHOOK_SECRET: string;
|
||||||
|
|
||||||
@CastToBoolean()
|
@CastToBoolean()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
TELEMETRY_ENABLED?: boolean;
|
TELEMETRY_ENABLED: boolean;
|
||||||
|
|
||||||
@CastToBoolean()
|
@CastToBoolean()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
TELEMETRY_ANONYMIZATION_ENABLED?: boolean;
|
TELEMETRY_ANONYMIZATION_ENABLED: boolean;
|
||||||
|
|
||||||
@CastToPositiveNumber()
|
@CastToPositiveNumber()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@ -82,6 +85,7 @@ export class EnvironmentVariables {
|
|||||||
PORT: number;
|
PORT: number;
|
||||||
|
|
||||||
// Database
|
// Database
|
||||||
|
@IsDefined()
|
||||||
@IsUrl({
|
@IsUrl({
|
||||||
protocols: ['postgres'],
|
protocols: ['postgres'],
|
||||||
require_tld: false,
|
require_tld: false,
|
||||||
@ -132,75 +136,79 @@ export class EnvironmentVariables {
|
|||||||
@CastToBoolean()
|
@CastToBoolean()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
AUTH_GOOGLE_ENABLED?: boolean;
|
AUTH_GOOGLE_ENABLED: boolean;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@ValidateIf((env) => env.AUTH_GOOGLE_ENABLED === true)
|
@ValidateIf((env) => env.AUTH_GOOGLE_ENABLED === true)
|
||||||
AUTH_GOOGLE_CLIENT_ID?: string;
|
AUTH_GOOGLE_CLIENT_ID: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@ValidateIf((env) => env.AUTH_GOOGLE_ENABLED === true)
|
@ValidateIf((env) => env.AUTH_GOOGLE_ENABLED === true)
|
||||||
AUTH_GOOGLE_CLIENT_SECRET?: string;
|
AUTH_GOOGLE_CLIENT_SECRET: string;
|
||||||
|
|
||||||
@IsUrl({ require_tld: false })
|
@IsUrl({ require_tld: false })
|
||||||
@ValidateIf((env) => env.AUTH_GOOGLE_ENABLED === true)
|
@ValidateIf((env) => env.AUTH_GOOGLE_ENABLED === true)
|
||||||
AUTH_GOOGLE_CALLBACK_URL?: string;
|
AUTH_GOOGLE_CALLBACK_URL: string;
|
||||||
|
|
||||||
// Storage
|
// Storage
|
||||||
@IsEnum(StorageDriverType)
|
@IsEnum(StorageDriverType)
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
STORAGE_TYPE?: StorageDriverType;
|
STORAGE_TYPE: StorageDriverType;
|
||||||
|
|
||||||
@ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3)
|
@ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3)
|
||||||
@IsAWSRegion()
|
@IsAWSRegion()
|
||||||
STORAGE_S3_REGION?: AwsRegion;
|
STORAGE_S3_REGION: AwsRegion;
|
||||||
|
|
||||||
@ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3)
|
@ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3)
|
||||||
@IsString()
|
@IsString()
|
||||||
STORAGE_S3_NAME?: string;
|
STORAGE_S3_NAME: string;
|
||||||
|
|
||||||
|
@ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3)
|
||||||
|
@IsString()
|
||||||
|
STORAGE_S3_ENDPOINT: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.Local)
|
@ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.Local)
|
||||||
STORAGE_LOCAL_PATH?: string;
|
STORAGE_LOCAL_PATH: string;
|
||||||
|
|
||||||
// Support
|
// Support
|
||||||
@IsEnum(SupportDriver)
|
@IsEnum(SupportDriver)
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
SUPPORT_DRIVER?: SupportDriver;
|
SUPPORT_DRIVER: SupportDriver;
|
||||||
|
|
||||||
@ValidateIf((env) => env.SUPPORT_DRIVER === SupportDriver.Front)
|
@ValidateIf((env) => env.SUPPORT_DRIVER === SupportDriver.Front)
|
||||||
@IsString()
|
@IsString()
|
||||||
SUPPORT_FRONT_CHAT_ID?: string;
|
SUPPORT_FRONT_CHAT_ID: string;
|
||||||
|
|
||||||
@ValidateIf((env) => env.SUPPORT_DRIVER === SupportDriver.Front)
|
@ValidateIf((env) => env.SUPPORT_DRIVER === SupportDriver.Front)
|
||||||
@IsString()
|
@IsString()
|
||||||
SUPPORT_FRONT_HMAC_KEY?: string;
|
SUPPORT_FRONT_HMAC_KEY: string;
|
||||||
|
|
||||||
@IsEnum(LoggerDriverType)
|
@IsEnum(LoggerDriverType)
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
LOGGER_DRIVER?: LoggerDriverType;
|
LOGGER_DRIVER: LoggerDriverType;
|
||||||
|
|
||||||
@IsEnum(ExceptionHandlerDriver)
|
@IsEnum(ExceptionHandlerDriver)
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
EXCEPTION_HANDLER_DRIVER?: ExceptionHandlerDriver;
|
EXCEPTION_HANDLER_DRIVER: ExceptionHandlerDriver;
|
||||||
|
|
||||||
@CastToLogLevelArray()
|
@CastToLogLevelArray()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
LOG_LEVELS?: LogLevel[];
|
LOG_LEVELS: LogLevel[];
|
||||||
|
|
||||||
@CastToStringArray()
|
@CastToStringArray()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
DEMO_WORKSPACE_IDS?: string[];
|
DEMO_WORKSPACE_IDS: string[];
|
||||||
|
|
||||||
@ValidateIf(
|
@ValidateIf(
|
||||||
(env) => env.EXCEPTION_HANDLER_DRIVER === ExceptionHandlerDriver.Sentry,
|
(env) => env.EXCEPTION_HANDLER_DRIVER === ExceptionHandlerDriver.Sentry,
|
||||||
)
|
)
|
||||||
@IsString()
|
@IsString()
|
||||||
SENTRY_DSN?: string;
|
SENTRY_DSN: string;
|
||||||
|
|
||||||
@IsDuration()
|
@IsDuration()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
PASSWORD_RESET_TOKEN_EXPIRES_IN?: number;
|
PASSWORD_RESET_TOKEN_EXPIRES_IN: string;
|
||||||
|
|
||||||
@CastToPositiveNumber()
|
@CastToPositiveNumber()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@ -220,13 +228,56 @@ export class EnvironmentVariables {
|
|||||||
@CastToBoolean()
|
@CastToBoolean()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
IS_SIGN_UP_DISABLED?: boolean;
|
IS_SIGN_UP_DISABLED: boolean;
|
||||||
|
|
||||||
@CastToPositiveNumber()
|
@CastToPositiveNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
MUTATION_MAXIMUM_RECORD_AFFECTED: number;
|
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>) => {
|
export const validate = (config: Record<string, unknown>) => {
|
||||||
const validatedConfig = plainToClass(EnvironmentVariables, config);
|
const validatedConfig = plainToClass(EnvironmentVariables, config);
|
||||||
|
|
||||||
@ -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 };
|
||||||
@ -3,7 +3,7 @@ import { ConfigModule } from '@nestjs/config';
|
|||||||
|
|
||||||
import { EnvironmentService } from './environment.service';
|
import { EnvironmentService } from './environment.service';
|
||||||
import { ConfigurableModuleClass } from './environment.module-definition';
|
import { ConfigurableModuleClass } from './environment.module-definition';
|
||||||
import { validate } from './environment.validation';
|
import { validate } from './environment-variables';
|
||||||
|
|
||||||
@Global()
|
@Global()
|
||||||
@Module({
|
@Module({
|
||||||
|
|||||||
@ -1,92 +1,23 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
/* 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 { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
|
|
||||||
import { EmailDriver } from 'src/integrations/email/interfaces/email.interface';
|
import { EnvironmentVariables } from 'src/integrations/environment/environment-variables';
|
||||||
|
import { EnvironmentDefault } from 'src/integrations/environment/environment.default';
|
||||||
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';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class EnvironmentService {
|
export class EnvironmentService {
|
||||||
constructor(private configService: ConfigService) {}
|
constructor(private configService: ConfigService) {}
|
||||||
|
|
||||||
isDebugMode(): boolean {
|
get<T extends keyof EnvironmentVariables>(key: T): EnvironmentVariables[T] {
|
||||||
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 {
|
|
||||||
return (
|
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 {
|
getServerUrl(): string {
|
||||||
const url = this.configService.get<string>('SERVER_URL')!;
|
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 {
|
getFrontAuthCallbackUrl(): string {
|
||||||
return (
|
return (
|
||||||
this.configService.get<string>('FRONT_AUTH_CALLBACK_URL') ??
|
this.configService.get<string>('FRONT_AUTH_CALLBACK_URL') ??
|
||||||
this.getFrontBaseUrl() + '/verify'
|
this.get('FRONT_BASE_URL') + '/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
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: check because it isn't called
|
||||||
getLoggerIsBufferEnabled(): boolean | undefined {
|
getLoggerIsBufferEnabled(): boolean | undefined {
|
||||||
return this.configService.get<boolean>('LOGGER_IS_BUFFER_ENABLED') ?? true;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ export const exceptionHandlerModuleFactory = async (
|
|||||||
environmentService: EnvironmentService,
|
environmentService: EnvironmentService,
|
||||||
adapterHost: HttpAdapterHost,
|
adapterHost: HttpAdapterHost,
|
||||||
): Promise<typeof OPTIONS_TYPE> => {
|
): Promise<typeof OPTIONS_TYPE> => {
|
||||||
const driverType = environmentService.getExceptionHandlerDriverType();
|
const driverType = environmentService.get('EXCEPTION_HANDLER_DRIVER');
|
||||||
|
|
||||||
switch (driverType) {
|
switch (driverType) {
|
||||||
case ExceptionHandlerDriver.Console: {
|
case ExceptionHandlerDriver.Console: {
|
||||||
@ -25,9 +25,9 @@ export const exceptionHandlerModuleFactory = async (
|
|||||||
return {
|
return {
|
||||||
type: ExceptionHandlerDriver.Sentry,
|
type: ExceptionHandlerDriver.Sentry,
|
||||||
options: {
|
options: {
|
||||||
dsn: environmentService.getSentryDSN() ?? '',
|
dsn: environmentService.get('SENTRY_DSN') ?? '',
|
||||||
serverInstance: adapterHost.httpAdapter?.getInstance(),
|
serverInstance: adapterHost.httpAdapter?.getInstance(),
|
||||||
debug: environmentService.isDebugMode(),
|
debug: environmentService.get('DEBUG_MODE'),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,11 +14,11 @@ import {
|
|||||||
export const fileStorageModuleFactory = async (
|
export const fileStorageModuleFactory = async (
|
||||||
environmentService: EnvironmentService,
|
environmentService: EnvironmentService,
|
||||||
): Promise<FileStorageModuleOptions> => {
|
): Promise<FileStorageModuleOptions> => {
|
||||||
const driverType = environmentService.getStorageDriverType();
|
const driverType = environmentService.get('STORAGE_TYPE');
|
||||||
|
|
||||||
switch (driverType) {
|
switch (driverType) {
|
||||||
case StorageDriverType.Local: {
|
case StorageDriverType.Local: {
|
||||||
const storagePath = environmentService.getStorageLocalPath();
|
const storagePath = environmentService.get('STORAGE_LOCAL_PATH');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: StorageDriverType.Local,
|
type: StorageDriverType.Local,
|
||||||
@ -28,9 +28,9 @@ export const fileStorageModuleFactory = async (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
case StorageDriverType.S3: {
|
case StorageDriverType.S3: {
|
||||||
const bucketName = environmentService.getStorageS3Name();
|
const bucketName = environmentService.get('STORAGE_S3_NAME');
|
||||||
const endpoint = environmentService.getStorageS3Endpoint();
|
const endpoint = environmentService.get('STORAGE_S3_ENDPOINT');
|
||||||
const region = environmentService.getStorageS3Region();
|
const region = environmentService.get('STORAGE_S3_REGION');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: StorageDriverType.S3,
|
type: StorageDriverType.S3,
|
||||||
|
|||||||
@ -12,8 +12,8 @@ import {
|
|||||||
export const loggerModuleFactory = async (
|
export const loggerModuleFactory = async (
|
||||||
environmentService: EnvironmentService,
|
environmentService: EnvironmentService,
|
||||||
): Promise<LoggerModuleOptions> => {
|
): Promise<LoggerModuleOptions> => {
|
||||||
const driverType = environmentService.getLoggerDriverType();
|
const driverType = environmentService.get('LOGGER_DRIVER');
|
||||||
const logLevels = environmentService.getLogLevels();
|
const logLevels = environmentService.get('LOG_LEVELS');
|
||||||
|
|
||||||
switch (driverType) {
|
switch (driverType) {
|
||||||
case LoggerDriverType.Console: {
|
case LoggerDriverType.Console: {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import {
|
|||||||
export const messageQueueModuleFactory = async (
|
export const messageQueueModuleFactory = async (
|
||||||
environmentService: EnvironmentService,
|
environmentService: EnvironmentService,
|
||||||
): Promise<MessageQueueModuleOptions> => {
|
): Promise<MessageQueueModuleOptions> => {
|
||||||
const driverType = environmentService.getMessageQueueDriverType();
|
const driverType = environmentService.get('MESSAGE_QUEUE_TYPE');
|
||||||
|
|
||||||
switch (driverType) {
|
switch (driverType) {
|
||||||
case MessageQueueDriverType.Sync: {
|
case MessageQueueDriverType.Sync: {
|
||||||
@ -22,7 +22,7 @@ export const messageQueueModuleFactory = async (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
case MessageQueueDriverType.PgBoss: {
|
case MessageQueueDriverType.PgBoss: {
|
||||||
const connectionString = environmentService.getPGDatabaseUrl();
|
const connectionString = environmentService.get('PG_DATABASE_URL');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: MessageQueueDriverType.PgBoss,
|
type: MessageQueueDriverType.PgBoss,
|
||||||
@ -32,8 +32,8 @@ export const messageQueueModuleFactory = async (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
case MessageQueueDriverType.BullMQ: {
|
case MessageQueueDriverType.BullMQ: {
|
||||||
const host = environmentService.getRedisHost();
|
const host = environmentService.get('REDIS_HOST');
|
||||||
const port = environmentService.getRedisPort();
|
const port = environmentService.get('REDIS_PORT');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: MessageQueueDriverType.BullMQ,
|
type: MessageQueueDriverType.BullMQ,
|
||||||
|
|||||||
@ -53,7 +53,7 @@ const bootstrap = async () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await app.listen(app.get(EnvironmentService).getPort());
|
await app.listen(app.get(EnvironmentService).get('PORT'));
|
||||||
};
|
};
|
||||||
|
|
||||||
bootstrap();
|
bootstrap();
|
||||||
|
|||||||
@ -26,8 +26,8 @@ export const metadataModuleFactory = async (
|
|||||||
resolvers: { JSON: GraphQLJSON },
|
resolvers: { JSON: GraphQLJSON },
|
||||||
plugins: [
|
plugins: [
|
||||||
useThrottler({
|
useThrottler({
|
||||||
ttl: environmentService.getApiRateLimitingTtl(),
|
ttl: environmentService.get('API_RATE_LIMITING_TTL'),
|
||||||
limit: environmentService.getApiRateLimitingLimit(),
|
limit: environmentService.get('API_RATE_LIMITING_LIMIT'),
|
||||||
identifyFn: (context) => {
|
identifyFn: (context) => {
|
||||||
return context.user?.id ?? context.req.ip ?? 'anonymous';
|
return context.user?.id ?? context.req.ip ?? 'anonymous';
|
||||||
},
|
},
|
||||||
@ -39,7 +39,7 @@ export const metadataModuleFactory = async (
|
|||||||
path: '/metadata',
|
path: '/metadata',
|
||||||
};
|
};
|
||||||
|
|
||||||
if (environmentService.isDebugMode()) {
|
if (environmentService.get('DEBUG_MODE')) {
|
||||||
config.renderGraphiQL = () => {
|
config.renderGraphiQL = () => {
|
||||||
return renderApolloPlayground({ path: 'metadata' });
|
return renderApolloPlayground({ path: 'metadata' });
|
||||||
};
|
};
|
||||||
|
|||||||
@ -48,8 +48,8 @@ export class GoogleAPIsRefreshAccessTokenService {
|
|||||||
const response = await axios.post(
|
const response = await axios.post(
|
||||||
'https://oauth2.googleapis.com/token',
|
'https://oauth2.googleapis.com/token',
|
||||||
{
|
{
|
||||||
client_id: this.environmentService.getAuthGoogleClientId(),
|
client_id: this.environmentService.get('AUTH_GOOGLE_CLIENT_ID'),
|
||||||
client_secret: this.environmentService.getAuthGoogleClientSecret(),
|
client_secret: this.environmentService.get('AUTH_GOOGLE_CLIENT_SECRET'),
|
||||||
refresh_token: refreshToken,
|
refresh_token: refreshToken,
|
||||||
grant_type: 'refresh_token',
|
grant_type: 'refresh_token',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -23,10 +23,12 @@ export class GoogleCalendarClientProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async getOAuth2Client(refreshToken: string): Promise<OAuth2Client> {
|
private async getOAuth2Client(refreshToken: string): Promise<OAuth2Client> {
|
||||||
const googleCalendarClientId =
|
const googleCalendarClientId = this.environmentService.get(
|
||||||
this.environmentService.getAuthGoogleClientId();
|
'AUTH_GOOGLE_CLIENT_ID',
|
||||||
const googleCalendarClientSecret =
|
);
|
||||||
this.environmentService.getAuthGoogleClientSecret();
|
const googleCalendarClientSecret = this.environmentService.get(
|
||||||
|
'AUTH_GOOGLE_CLIENT_SECRET',
|
||||||
|
);
|
||||||
|
|
||||||
const oAuth2Client = new google.auth.OAuth2(
|
const oAuth2Client = new google.auth.OAuth2(
|
||||||
googleCalendarClientId,
|
googleCalendarClientId,
|
||||||
|
|||||||
@ -21,9 +21,9 @@ export class GmailClientProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async getOAuth2Client(refreshToken: string): Promise<OAuth2Client> {
|
private async getOAuth2Client(refreshToken: string): Promise<OAuth2Client> {
|
||||||
const gmailClientId = this.environmentService.getAuthGoogleClientId();
|
const gmailClientId = this.environmentService.get('AUTH_GOOGLE_CLIENT_ID');
|
||||||
const gmailClientSecret =
|
const gmailClientSecret =
|
||||||
this.environmentService.getAuthGoogleClientSecret();
|
this.environmentService.get('AUTH_GOOGLE_CLIENT_SECRET');
|
||||||
|
|
||||||
const oAuth2Client = new google.auth.OAuth2(
|
const oAuth2Client = new google.auth.OAuth2(
|
||||||
gmailClientId,
|
gmailClientId,
|
||||||
|
|||||||
@ -45,9 +45,9 @@ export class CleanInactiveWorkspaceJob
|
|||||||
private readonly environmentService: EnvironmentService,
|
private readonly environmentService: EnvironmentService,
|
||||||
) {
|
) {
|
||||||
this.inactiveDaysBeforeDelete =
|
this.inactiveDaysBeforeDelete =
|
||||||
this.environmentService.getInactiveDaysBeforeDelete();
|
this.environmentService.get('WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION');
|
||||||
this.inactiveDaysBeforeEmail =
|
this.inactiveDaysBeforeEmail =
|
||||||
this.environmentService.getInactiveDaysBeforeEmail();
|
this.environmentService.get('WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION');
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMostRecentUpdatedAt(
|
async getMostRecentUpdatedAt(
|
||||||
@ -133,8 +133,8 @@ export class CleanInactiveWorkspaceJob
|
|||||||
|
|
||||||
this.emailService.send({
|
this.emailService.send({
|
||||||
to: workspaceMember.email,
|
to: workspaceMember.email,
|
||||||
bcc: this.environmentService.getEmailSystemAddress(),
|
bcc: this.environmentService.get('EMAIL_SYSTEM_ADDRESS'),
|
||||||
from: `${this.environmentService.getEmailFromName()} <${this.environmentService.getEmailFromAddress()}>`,
|
from: `${this.environmentService.get('EMAIL_FROM_NAME')} <${this.environmentService.get('EMAIL_FROM_ADDRESS')}>`,
|
||||||
subject: 'Action Needed to Prevent Workspace Deletion',
|
subject: 'Action Needed to Prevent Workspace Deletion',
|
||||||
html,
|
html,
|
||||||
text,
|
text,
|
||||||
@ -179,8 +179,8 @@ export class CleanInactiveWorkspaceJob
|
|||||||
});
|
});
|
||||||
|
|
||||||
await this.emailService.send({
|
await this.emailService.send({
|
||||||
to: this.environmentService.getEmailSystemAddress(),
|
to: this.environmentService.get('EMAIL_SYSTEM_ADDRESS'),
|
||||||
from: `${this.environmentService.getEmailFromName()} <${this.environmentService.getEmailFromAddress()}>`,
|
from: `${this.environmentService.get('EMAIL_FROM_NAME')} <${this.environmentService.get('EMAIL_FROM_ADDRESS')}>`,
|
||||||
subject: 'Action Needed to Delete Workspaces',
|
subject: 'Action Needed to Delete Workspaces',
|
||||||
html,
|
html,
|
||||||
text,
|
text,
|
||||||
|
|||||||
@ -307,7 +307,7 @@ export class WorkspaceQueryRunnerService {
|
|||||||
): Promise<Record[] | undefined> {
|
): Promise<Record[] | undefined> {
|
||||||
const { workspaceId, objectMetadataItem } = options;
|
const { workspaceId, objectMetadataItem } = options;
|
||||||
const maximumRecordAffected =
|
const maximumRecordAffected =
|
||||||
this.environmentService.getMutationMaximumRecordAffected();
|
this.environmentService.get('MUTATION_MAXIMUM_RECORD_AFFECTED');
|
||||||
const query = await this.workspaceQueryBuilderFactory.updateMany(args, {
|
const query = await this.workspaceQueryBuilderFactory.updateMany(args, {
|
||||||
...options,
|
...options,
|
||||||
atMost: maximumRecordAffected,
|
atMost: maximumRecordAffected,
|
||||||
@ -339,7 +339,7 @@ export class WorkspaceQueryRunnerService {
|
|||||||
): Promise<Record[] | undefined> {
|
): Promise<Record[] | undefined> {
|
||||||
const { workspaceId, objectMetadataItem } = options;
|
const { workspaceId, objectMetadataItem } = options;
|
||||||
const maximumRecordAffected =
|
const maximumRecordAffected =
|
||||||
this.environmentService.getMutationMaximumRecordAffected();
|
this.environmentService.get('MUTATION_MAXIMUM_RECORD_AFFECTED');
|
||||||
const query = await this.workspaceQueryBuilderFactory.deleteMany(args, {
|
const query = await this.workspaceQueryBuilderFactory.deleteMany(args, {
|
||||||
...options,
|
...options,
|
||||||
atMost: maximumRecordAffected,
|
atMost: maximumRecordAffected,
|
||||||
|
|||||||
Reference in New Issue
Block a user