diff --git a/server/src/app.module.ts b/server/src/app.module.ts index de01d3b4b..64aee7acc 100644 --- a/server/src/app.module.ts +++ b/server/src/app.module.ts @@ -33,8 +33,8 @@ import GraphQLJSON from 'graphql-type-json'; PrismaModule, HealthModule, AbilityModule, - CoreModule, IntegrationsModule, + CoreModule, ], providers: [AppService], }) diff --git a/server/src/core/auth/auth.module.ts b/server/src/core/auth/auth.module.ts index 477ba3676..0ab8cbd82 100644 --- a/server/src/core/auth/auth.module.ts +++ b/server/src/core/auth/auth.module.ts @@ -3,7 +3,6 @@ import { JwtModule } from '@nestjs/jwt'; import { JwtAuthStrategy } from './strategies/jwt.auth.strategy'; import { AuthService } from './services/auth.service'; import { GoogleAuthController } from './controllers/google-auth.controller'; -import { GoogleStrategy } from './strategies/google.auth.strategy'; import { PrismaService } from 'src/database/prisma.service'; import { UserModule } from '../user/user.module'; import { VerifyAuthController } from './controllers/verify-auth.controller'; @@ -30,7 +29,6 @@ const jwtModule = JwtModule.registerAsync({ AuthService, TokenService, JwtAuthStrategy, - GoogleStrategy, PrismaService, AuthResolver, ], diff --git a/server/src/core/auth/guards/google-provider-enabled.guard.ts b/server/src/core/auth/guards/google-provider-enabled.guard.ts index baf92d59a..75eb412b5 100644 --- a/server/src/core/auth/guards/google-provider-enabled.guard.ts +++ b/server/src/core/auth/guards/google-provider-enabled.guard.ts @@ -1,14 +1,17 @@ -import { Injectable, CanActivate, HttpException } from '@nestjs/common'; +import { Injectable, CanActivate, NotFoundException } from '@nestjs/common'; import { Observable } from 'rxjs'; import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { GoogleStrategy } from '../strategies/google.auth.strategy'; @Injectable() export class GoogleProviderEnabledGuard implements CanActivate { constructor(private readonly environmentService: EnvironmentService) {} canActivate(): boolean | Promise | Observable { if (!this.environmentService.getAuthGoogleEnabled()) { - throw new HttpException('Google auth is not enabled', 404); + throw new NotFoundException('Google auth is not enabled'); } + + new GoogleStrategy(this.environmentService); return true; } } diff --git a/server/src/core/auth/strategies/google.auth.strategy.ts b/server/src/core/auth/strategies/google.auth.strategy.ts index c71e38b6c..a14f52f7a 100644 --- a/server/src/core/auth/strategies/google.auth.strategy.ts +++ b/server/src/core/auth/strategies/google.auth.strategy.ts @@ -16,17 +16,10 @@ export type GoogleRequest = Request & { @Injectable() export class GoogleStrategy extends PassportStrategy(Strategy, 'google') { constructor(environmentService: EnvironmentService) { - const isAuthGoogleEnabled = environmentService.getAuthGoogleEnabled(); super({ - clientID: isAuthGoogleEnabled - ? environmentService.getAuthGoogleClientId() - : 'disabled', - clientSecret: isAuthGoogleEnabled - ? environmentService.getAuthGoogleClientSecret() - : 'disabled', - callbackURL: isAuthGoogleEnabled - ? environmentService.getAuthGoogleCallbackUrl() - : 'disabled', + clientID: environmentService.getAuthGoogleClientId(), + clientSecret: environmentService.getAuthGoogleClientSecret(), + callbackURL: environmentService.getAuthGoogleCallbackUrl(), scope: ['email', 'profile'], }); } diff --git a/server/src/integrations/environment/decorators/cast-to-boolean.decorator.ts b/server/src/integrations/environment/decorators/cast-to-boolean.decorator.ts new file mode 100644 index 000000000..fee9e69bf --- /dev/null +++ b/server/src/integrations/environment/decorators/cast-to-boolean.decorator.ts @@ -0,0 +1,18 @@ +import { Transform } from 'class-transformer'; + +export function CastToBoolean() { + return Transform(({ value }: { value: string }) => toBoolean(value)); +} + +const toBoolean = (value: any) => { + if (typeof value === 'boolean') { + return value; + } + if (['true', 'on', 'yes', '1'].includes(value.toLowerCase())) { + return true; + } + if (['false', 'off', 'no', '0'].includes(value.toLowerCase())) { + return false; + } + return undefined; +}; diff --git a/server/src/integrations/environment/environment.validation.ts b/server/src/integrations/environment/environment.validation.ts index 0ea9fede1..1ef2f5e4e 100644 --- a/server/src/integrations/environment/environment.validation.ts +++ b/server/src/integrations/environment/environment.validation.ts @@ -13,6 +13,7 @@ import { IsDuration } from './decorators/is-duration.decorator'; import { StorageType } from './interfaces/storage.interface'; import { AwsRegion } from './interfaces/aws-region.interface'; import { IsAWSRegion } from './decorators/is-aws-region.decorator'; +import { CastToBoolean } from './decorators/cast-to-boolean.decorator'; export class EnvironmentVariables { // Database @@ -39,7 +40,7 @@ export class EnvironmentVariables { @IsUrl({ require_tld: false }) FRONT_AUTH_CALLBACK_URL: string; - @Transform(({ value }) => envValueToBoolean(value)) + @CastToBoolean() @IsOptional() @IsBoolean() AUTH_GOOGLE_ENABLED?: boolean; @@ -75,27 +76,10 @@ export class EnvironmentVariables { } export function validate(config: Record) { - const validatedConfig = plainToClass(EnvironmentVariables, config, { - enableImplicitConversion: false, - }); + const validatedConfig = plainToClass(EnvironmentVariables, config); - const errors = validateSync(validatedConfig, { - skipMissingProperties: false, - }); + const errors = validateSync(validatedConfig); assert(!errors.length, errors.toString()); return validatedConfig; } - -const envValueToBoolean = (value: any) => { - if (typeof value === 'boolean') { - return value; - } - if (['true', 'on', 'yes', '1'].includes(value.toLowerCase())) { - return true; - } - if (['false', 'off', 'no', '0'].includes(value.toLowerCase())) { - return false; - } - return undefined; -};