fix: config service precedence
This commit is contained in:
@@ -80,7 +80,7 @@ import { loadInfraConfiguration } from './infra-config/helper';
|
||||
],
|
||||
}),
|
||||
UserModule,
|
||||
AuthModule,
|
||||
AuthModule.register(),
|
||||
AdminModule,
|
||||
UserSettingsModule,
|
||||
UserEnvironmentsModule,
|
||||
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
Body,
|
||||
Controller,
|
||||
Get,
|
||||
InternalServerErrorException,
|
||||
Post,
|
||||
Query,
|
||||
Request,
|
||||
@@ -31,11 +30,15 @@ import { MicrosoftSSOGuard } from './guards/microsoft-sso-.guard';
|
||||
import { ThrottlerBehindProxyGuard } from 'src/guards/throttler-behind-proxy.guard';
|
||||
import { SkipThrottle } from '@nestjs/throttler';
|
||||
import { AUTH_PROVIDER_NOT_SPECIFIED } from 'src/errors';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
@UseGuards(ThrottlerBehindProxyGuard)
|
||||
@Controller({ path: 'auth', version: '1' })
|
||||
export class AuthController {
|
||||
constructor(private authService: AuthService) {}
|
||||
constructor(
|
||||
private authService: AuthService,
|
||||
private configService: ConfigService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
** Route to initiate magic-link auth for a users email
|
||||
@@ -45,8 +48,14 @@ export class AuthController {
|
||||
@Body() authData: SignInMagicDto,
|
||||
@Query('origin') origin: string,
|
||||
) {
|
||||
if (!authProviderCheck(AuthProvider.EMAIL))
|
||||
if (
|
||||
!authProviderCheck(
|
||||
AuthProvider.EMAIL,
|
||||
this.configService.get('INFRA.VITE_ALLOWED_AUTH_PROVIDERS'),
|
||||
)
|
||||
) {
|
||||
throwHTTPErr({ message: AUTH_PROVIDER_NOT_SPECIFIED, statusCode: 404 });
|
||||
}
|
||||
|
||||
const deviceIdToken = await this.authService.signInMagicLink(
|
||||
authData.email,
|
||||
|
||||
@@ -13,6 +13,7 @@ import { GithubStrategy } from './strategies/github.strategy';
|
||||
import { MicrosoftStrategy } from './strategies/microsoft.strategy';
|
||||
import { AuthProvider, authProviderCheck } from './helper';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import { loadInfraConfiguration } from 'src/infra-config/helper';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -28,14 +29,29 @@ import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
}),
|
||||
}),
|
||||
],
|
||||
providers: [
|
||||
AuthService,
|
||||
JwtStrategy,
|
||||
RTJwtStrategy,
|
||||
...(authProviderCheck(AuthProvider.GOOGLE) ? [GoogleStrategy] : []),
|
||||
...(authProviderCheck(AuthProvider.GITHUB) ? [GithubStrategy] : []),
|
||||
...(authProviderCheck(AuthProvider.MICROSOFT) ? [MicrosoftStrategy] : []),
|
||||
],
|
||||
providers: [AuthService, JwtStrategy, RTJwtStrategy],
|
||||
controllers: [AuthController],
|
||||
})
|
||||
export class AuthModule {}
|
||||
export class AuthModule {
|
||||
static async register() {
|
||||
const env = await loadInfraConfiguration();
|
||||
const allowedAuthProviders = env.INFRA.VITE_ALLOWED_AUTH_PROVIDERS;
|
||||
|
||||
const providers = [
|
||||
...(authProviderCheck(AuthProvider.GOOGLE, allowedAuthProviders)
|
||||
? [GoogleStrategy]
|
||||
: []),
|
||||
...(authProviderCheck(AuthProvider.GITHUB, allowedAuthProviders)
|
||||
? [GithubStrategy]
|
||||
: []),
|
||||
...(authProviderCheck(AuthProvider.MICROSOFT, allowedAuthProviders)
|
||||
? [MicrosoftStrategy]
|
||||
: []),
|
||||
];
|
||||
|
||||
return {
|
||||
module: AuthModule,
|
||||
providers,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,25 @@ import { AuthGuard } from '@nestjs/passport';
|
||||
import { AuthProvider, authProviderCheck, throwHTTPErr } from '../helper';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AUTH_PROVIDER_NOT_SPECIFIED } from 'src/errors';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
@Injectable()
|
||||
export class GithubSSOGuard extends AuthGuard('github') implements CanActivate {
|
||||
constructor(private readonly configService: ConfigService) {
|
||||
super();
|
||||
}
|
||||
|
||||
canActivate(
|
||||
context: ExecutionContext,
|
||||
): boolean | Promise<boolean> | Observable<boolean> {
|
||||
if (!authProviderCheck(AuthProvider.GITHUB))
|
||||
if (
|
||||
!authProviderCheck(
|
||||
AuthProvider.GITHUB,
|
||||
this.configService.get('INFRA.VITE_ALLOWED_AUTH_PROVIDERS'),
|
||||
)
|
||||
) {
|
||||
throwHTTPErr({ message: AUTH_PROVIDER_NOT_SPECIFIED, statusCode: 404 });
|
||||
}
|
||||
|
||||
return super.canActivate(context);
|
||||
}
|
||||
|
||||
@@ -3,14 +3,25 @@ import { AuthGuard } from '@nestjs/passport';
|
||||
import { AuthProvider, authProviderCheck, throwHTTPErr } from '../helper';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AUTH_PROVIDER_NOT_SPECIFIED } from 'src/errors';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
@Injectable()
|
||||
export class GoogleSSOGuard extends AuthGuard('google') implements CanActivate {
|
||||
constructor(private readonly configService: ConfigService) {
|
||||
super();
|
||||
}
|
||||
|
||||
canActivate(
|
||||
context: ExecutionContext,
|
||||
): boolean | Promise<boolean> | Observable<boolean> {
|
||||
if (!authProviderCheck(AuthProvider.GOOGLE))
|
||||
if (
|
||||
!authProviderCheck(
|
||||
AuthProvider.GOOGLE,
|
||||
this.configService.get('INFRA.VITE_ALLOWED_AUTH_PROVIDERS'),
|
||||
)
|
||||
) {
|
||||
throwHTTPErr({ message: AUTH_PROVIDER_NOT_SPECIFIED, statusCode: 404 });
|
||||
}
|
||||
|
||||
return super.canActivate(context);
|
||||
}
|
||||
|
||||
@@ -3,20 +3,31 @@ import { AuthGuard } from '@nestjs/passport';
|
||||
import { AuthProvider, authProviderCheck, throwHTTPErr } from '../helper';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AUTH_PROVIDER_NOT_SPECIFIED } from 'src/errors';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
@Injectable()
|
||||
export class MicrosoftSSOGuard
|
||||
extends AuthGuard('microsoft')
|
||||
implements CanActivate
|
||||
{
|
||||
constructor(private readonly configService: ConfigService) {
|
||||
super();
|
||||
}
|
||||
|
||||
canActivate(
|
||||
context: ExecutionContext,
|
||||
): boolean | Promise<boolean> | Observable<boolean> {
|
||||
if (!authProviderCheck(AuthProvider.MICROSOFT))
|
||||
if (
|
||||
!authProviderCheck(
|
||||
AuthProvider.MICROSOFT,
|
||||
this.configService.get('INFRA.VITE_ALLOWED_AUTH_PROVIDERS'),
|
||||
)
|
||||
) {
|
||||
throwHTTPErr({
|
||||
message: AUTH_PROVIDER_NOT_SPECIFIED,
|
||||
statusCode: 404,
|
||||
});
|
||||
}
|
||||
|
||||
return super.canActivate(context);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import * as cookie from 'cookie';
|
||||
import { AUTH_PROVIDER_NOT_SPECIFIED, COOKIES_NOT_FOUND } from 'src/errors';
|
||||
import { throwErr } from 'src/utils';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { loadInfraConfiguration } from 'src/infra-config/helper';
|
||||
|
||||
enum AuthTokenType {
|
||||
ACCESS_TOKEN = 'access_token',
|
||||
@@ -117,18 +118,18 @@ export const subscriptionContextCookieParser = (rawCookies: string) => {
|
||||
* @param provider Provider we want to check the presence of
|
||||
* @returns Boolean if provider specified is present or not
|
||||
*/
|
||||
export function authProviderCheck(provider: string) {
|
||||
const configService = new ConfigService();
|
||||
|
||||
export function authProviderCheck(
|
||||
provider: string,
|
||||
VITE_ALLOWED_AUTH_PROVIDERS: string,
|
||||
) {
|
||||
if (!provider) {
|
||||
throwErr(AUTH_PROVIDER_NOT_SPECIFIED);
|
||||
}
|
||||
|
||||
const envVariables = configService.get('VITE_ALLOWED_AUTH_PROVIDERS')
|
||||
? configService
|
||||
.get('VITE_ALLOWED_AUTH_PROVIDERS')
|
||||
.split(',')
|
||||
.map((provider) => provider.trim().toUpperCase())
|
||||
const envVariables = VITE_ALLOWED_AUTH_PROVIDERS
|
||||
? VITE_ALLOWED_AUTH_PROVIDERS.split(',').map((provider) =>
|
||||
provider.trim().toUpperCase(),
|
||||
)
|
||||
: [];
|
||||
|
||||
if (!envVariables.includes(provider.toUpperCase())) return false;
|
||||
|
||||
@@ -15,8 +15,8 @@ export class GithubStrategy extends PassportStrategy(Strategy) {
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
super({
|
||||
clientID: configService.get('GITHUB_CLIENT_ID'),
|
||||
clientSecret: configService.get('GITHUB_CLIENT_SECRET'),
|
||||
clientID: configService.get('INFRA.GITHUB_CLIENT_ID'),
|
||||
clientSecret: configService.get('INFRA.GITHUB_CLIENT_SECRET'),
|
||||
callbackURL: configService.get('GITHUB_CALLBACK_URL'),
|
||||
scope: [configService.get('GITHUB_SCOPE')],
|
||||
store: true,
|
||||
|
||||
@@ -15,8 +15,8 @@ export class GoogleStrategy extends PassportStrategy(Strategy) {
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
super({
|
||||
clientID: configService.get('GOOGLE_CLIENT_ID'),
|
||||
clientSecret: configService.get('GOOGLE_CLIENT_SECRET'),
|
||||
clientID: configService.get('INFRA.GOOGLE_CLIENT_ID'),
|
||||
clientSecret: configService.get('INFRA.GOOGLE_CLIENT_SECRET'),
|
||||
callbackURL: configService.get('GOOGLE_CALLBACK_URL'),
|
||||
scope: configService.get('GOOGLE_SCOPE').split(','),
|
||||
passReqToCallback: true,
|
||||
|
||||
@@ -15,8 +15,8 @@ export class MicrosoftStrategy extends PassportStrategy(Strategy) {
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
super({
|
||||
clientID: configService.get('MICROSOFT_CLIENT_ID'),
|
||||
clientSecret: configService.get('MICROSOFT_CLIENT_SECRET'),
|
||||
clientID: configService.get('INFRA.MICROSOFT_CLIENT_ID'),
|
||||
clientSecret: configService.get('INFRA.MICROSOFT_CLIENT_SECRET'),
|
||||
callbackURL: configService.get('MICROSOFT_CALLBACK_URL'),
|
||||
scope: [configService.get('MICROSOFT_SCOPE')],
|
||||
tenant: configService.get('MICROSOFT_TENANT'),
|
||||
|
||||
@@ -16,7 +16,7 @@ export async function loadInfraConfiguration() {
|
||||
environmentObject[infraConfig.name] = infraConfig.value;
|
||||
});
|
||||
|
||||
return environmentObject;
|
||||
return { INFRA: environmentObject };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,7 +24,10 @@ export async function loadInfraConfiguration() {
|
||||
* (Docker will re-start the app)
|
||||
*/
|
||||
export function stopApp() {
|
||||
console.log('Stopping app in 5 seconds...');
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('Stopping app now...');
|
||||
process.exit();
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@ async function bootstrap() {
|
||||
console.log(`Running in production: ${configService.get('PRODUCTION')}`);
|
||||
console.log(`Port: ${configService.get('PORT')}`);
|
||||
|
||||
checkEnvironmentAuthProvider();
|
||||
checkEnvironmentAuthProvider(
|
||||
configService.get('VITE_ALLOWED_AUTH_PROVIDERS'),
|
||||
);
|
||||
|
||||
app.use(
|
||||
session({
|
||||
|
||||
@@ -165,21 +165,20 @@ export function isValidLength(title: string, length: number) {
|
||||
* It checks if the "VITE_ALLOWED_AUTH_PROVIDERS" environment variable is properly set or not.
|
||||
* If not, it throws an error.
|
||||
*/
|
||||
export function checkEnvironmentAuthProvider() {
|
||||
const configService = new ConfigService();
|
||||
|
||||
if (!configService.get('VITE_ALLOWED_AUTH_PROVIDERS')) {
|
||||
export function checkEnvironmentAuthProvider(
|
||||
VITE_ALLOWED_AUTH_PROVIDERS: string,
|
||||
) {
|
||||
if (!VITE_ALLOWED_AUTH_PROVIDERS) {
|
||||
throw new Error(ENV_NOT_FOUND_KEY_AUTH_PROVIDERS);
|
||||
}
|
||||
|
||||
if (configService.get('VITE_ALLOWED_AUTH_PROVIDERS') === '') {
|
||||
if (VITE_ALLOWED_AUTH_PROVIDERS === '') {
|
||||
throw new Error(ENV_EMPTY_AUTH_PROVIDERS);
|
||||
}
|
||||
|
||||
const givenAuthProviders = configService
|
||||
.get('VITE_ALLOWED_AUTH_PROVIDERS')
|
||||
.split(',')
|
||||
.map((provider) => provider.toLocaleUpperCase());
|
||||
const givenAuthProviders = VITE_ALLOWED_AUTH_PROVIDERS.split(',').map(
|
||||
(provider) => provider.toLocaleUpperCase(),
|
||||
);
|
||||
const supportedAuthProviders = Object.values(AuthProvider).map(
|
||||
(provider: string) => provider.toLocaleUpperCase(),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user