mirror of
https://github.com/ToolJet/ToolJet
synced 2026-04-21 13:37:28 +00:00
reverted helmet interceptor
This commit is contained in:
parent
394be5ff34
commit
8d9d86cf2c
6 changed files with 122 additions and 107 deletions
22
CODEOWNERS
Normal file
22
CODEOWNERS
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Code owners for specific package.json and package-lock.json files
|
||||
/server/package.json @shah21 @gsmithun4 @adishm98
|
||||
/server/package-lock.json @shah21 @gsmithun4 @adishm98
|
||||
|
||||
/frontend/package.json @shah21 @gsmithun4 @adishm98
|
||||
/frontend/package-lock.json @shah21 @gsmithun4 @adishm98
|
||||
|
||||
/marketplace/package.json @shah21 @gsmithun4 @adishm98
|
||||
/marketplace/package-lock.json @shah21 @gsmithun4 @adishm98
|
||||
|
||||
/cypress/package.json @shah21 @gsmithun4 @adishm98
|
||||
/cypress/package-lock.json @shah21 @gsmithun4 @adishm98
|
||||
|
||||
/plugins/package.json @shah21 @gsmithun4 @adishm98
|
||||
/plugins/package-lock.json @shah21 @gsmithun4 @adishm98
|
||||
|
||||
/package.json @shah21 @gsmithun4 @adishm98
|
||||
/package-lock.json @shah21 @gsmithun4 @adishm98
|
||||
|
||||
# Server service files
|
||||
/server/src/services/email.service.ts @shah21 @gsmithun4
|
||||
/server/src/mails @shah21 @gsmithun4
|
||||
|
|
@ -45,10 +45,8 @@ import { ImportExportResourcesModule } from './modules/import_export_resources/i
|
|||
import { UserResourcePermissionsModule } from '@module/user_resource_permissions/user_resource_permissions.module';
|
||||
import { PermissionsModule } from '@module/permissions/permissions.module';
|
||||
import { GetConnection } from './helpers/getconnection';
|
||||
import { APP_INTERCEPTOR } from '@nestjs/core/constants';
|
||||
import { HelmetInterceptor } from './interceptors/helmet.interceptor';
|
||||
import { CustomHeadersInterceptor } from './interceptors/custom-headers.interceptors';
|
||||
import { InstanceSettingsModule } from '@instance-settings/module';
|
||||
import { StaticFileServerModule } from '@module/static_file_server/static_file_server.module';
|
||||
|
||||
const imports = [
|
||||
ScheduleModule.forRoot(),
|
||||
|
|
@ -109,6 +107,7 @@ const imports = [
|
|||
CopilotModule,
|
||||
OrganizationConstantModule,
|
||||
TooljetDbModule,
|
||||
StaticFileServerModule
|
||||
];
|
||||
|
||||
if (process.env.SERVE_CLIENT !== 'false' && process.env.NODE_ENV === 'production') {
|
||||
|
|
@ -146,14 +145,6 @@ if (process.env.ENABLE_TOOLJET_DB === 'true') {
|
|||
EmailService,
|
||||
SeedsService,
|
||||
GetConnection,
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
useClass: HelmetInterceptor,
|
||||
},
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
useClass: CustomHeadersInterceptor,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class AppModule implements OnModuleInit {
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class CustomHeadersInterceptor implements NestInterceptor {
|
||||
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||
return next.handle().pipe(
|
||||
map((data) => {
|
||||
const response = context.switchToHttp().getResponse();
|
||||
response.setHeader('Permissions-Policy', 'geolocation=(self), camera=(), microphone=()');
|
||||
response.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
|
||||
return data;
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
||||
import { Observable } from 'rxjs';
|
||||
import * as helmet from 'helmet';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
@Injectable()
|
||||
export class HelmetInterceptor implements NestInterceptor {
|
||||
private readonly helmet: ReturnType<typeof helmet>;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
const host = new URL(this.configService.get('TOOLJET_HOST'));
|
||||
const domain = host.hostname;
|
||||
this.helmet = helmet({
|
||||
contentSecurityPolicy: {
|
||||
useDefaults: true,
|
||||
directives: {
|
||||
upgradeInsecureRequests: null,
|
||||
'img-src': ['*', 'data:', 'blob:'],
|
||||
'script-src': [
|
||||
'maps.googleapis.com',
|
||||
'storage.googleapis.com',
|
||||
'apis.google.com',
|
||||
'accounts.google.com',
|
||||
"'self'",
|
||||
"'unsafe-inline'",
|
||||
"'unsafe-eval'",
|
||||
'blob:',
|
||||
'https://unpkg.com/@babel/standalone@7.17.9/babel.min.js',
|
||||
'https://unpkg.com/react@16.7.0/umd/react.production.min.js',
|
||||
'https://unpkg.com/react-dom@16.7.0/umd/react-dom.production.min.js',
|
||||
'cdn.skypack.dev',
|
||||
'cdn.jsdelivr.net',
|
||||
'https://esm.sh',
|
||||
'www.googletagmanager.com',
|
||||
],
|
||||
'default-src': [
|
||||
'maps.googleapis.com',
|
||||
'storage.googleapis.com',
|
||||
'apis.google.com',
|
||||
'accounts.google.com',
|
||||
'*.sentry.io',
|
||||
"'self'",
|
||||
'blob:',
|
||||
'www.googletagmanager.com',
|
||||
],
|
||||
'connect-src': ['ws://' + domain, "'self'", '*'],
|
||||
'frame-ancestors': ['*'],
|
||||
'frame-src': ['*'],
|
||||
},
|
||||
},
|
||||
frameguard:
|
||||
this.configService.get('DISABLE_APP_EMBED') !== 'true' ||
|
||||
this.configService.get('ENABLE_PRIVATE_APP_EMBED') === 'true'
|
||||
? false
|
||||
: { action: 'deny' },
|
||||
hidePoweredBy: true,
|
||||
referrerPolicy: {
|
||||
policy: 'no-referrer',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||
const httpContext = context.switchToHttp();
|
||||
const request = httpContext.getRequest();
|
||||
const response = httpContext.getResponse();
|
||||
|
||||
return new Observable((subscriber) => {
|
||||
this.helmet(request, response, () => {
|
||||
next.handle().subscribe(subscriber);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import { RequestMethod, ValidationPipe, VersioningType, VERSION_NEUTRAL } from '
|
|||
import { ConfigService } from '@nestjs/config';
|
||||
import { bootstrap as globalAgentBootstrap } from 'global-agent';
|
||||
import { join } from 'path';
|
||||
import * as helmet from 'helmet';
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
|
|
@ -39,6 +40,72 @@ function replaceSubpathPlaceHoldersInStaticAssets() {
|
|||
}
|
||||
}
|
||||
|
||||
function setSecurityHeaders(app, configService) {
|
||||
const tooljetHost = configService.get('TOOLJET_HOST');
|
||||
const host = new URL(tooljetHost);
|
||||
const domain = host.hostname;
|
||||
|
||||
app.enableCors({
|
||||
origin: configService.get('ENABLE_CORS') === 'true' || tooljetHost,
|
||||
credentials: true,
|
||||
});
|
||||
|
||||
app.use(helmet({
|
||||
contentSecurityPolicy: {
|
||||
useDefaults: true,
|
||||
directives: {
|
||||
upgradeInsecureRequests: null,
|
||||
'img-src': ['*', 'data:', 'blob:'],
|
||||
'script-src': [
|
||||
'maps.googleapis.com',
|
||||
'storage.googleapis.com',
|
||||
'apis.google.com',
|
||||
'accounts.google.com',
|
||||
"'self'",
|
||||
"'unsafe-inline'",
|
||||
"'unsafe-eval'",
|
||||
'blob:',
|
||||
'https://unpkg.com/@babel/standalone@7.17.9/babel.min.js',
|
||||
'https://unpkg.com/react@16.7.0/umd/react.production.min.js',
|
||||
'https://unpkg.com/react-dom@16.7.0/umd/react-dom.production.min.js',
|
||||
'cdn.skypack.dev',
|
||||
'cdn.jsdelivr.net',
|
||||
'https://esm.sh',
|
||||
'www.googletagmanager.com',
|
||||
],
|
||||
'default-src': [
|
||||
'maps.googleapis.com',
|
||||
'storage.googleapis.com',
|
||||
'apis.google.com',
|
||||
'accounts.google.com',
|
||||
'*.sentry.io',
|
||||
"'self'",
|
||||
'blob:',
|
||||
'www.googletagmanager.com',
|
||||
],
|
||||
'connect-src': ['ws://' + domain, "'self'", '*'],
|
||||
'frame-ancestors': ['*'],
|
||||
'frame-src': ['*'],
|
||||
},
|
||||
},
|
||||
frameguard:
|
||||
configService.get('DISABLE_APP_EMBED') !== 'true' ||
|
||||
configService.get('ENABLE_PRIVATE_APP_EMBED') === 'true'
|
||||
? false
|
||||
: { action: 'deny' },
|
||||
hidePoweredBy: true,
|
||||
referrerPolicy: {
|
||||
policy: 'no-referrer',
|
||||
},
|
||||
}));
|
||||
|
||||
app.use((req, res, next) => {
|
||||
res.setHeader('Permissions-Policy', 'geolocation=(self), camera=(), microphone=()');
|
||||
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
|
||||
return next();
|
||||
});
|
||||
}
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
|
||||
bufferLogs: true,
|
||||
|
|
@ -64,20 +131,17 @@ async function bootstrap() {
|
|||
app.setGlobalPrefix(UrlPrefix + 'api', {
|
||||
exclude: pathsToExclude,
|
||||
});
|
||||
app.enableCors({
|
||||
origin: process.env.ENABLE_CORS === 'true' || process.env.TOOLJET_HOST,
|
||||
credentials: true,
|
||||
});
|
||||
app.use(compression());
|
||||
app.use(cookieParser());
|
||||
app.use(json({ limit: '50mb' }));
|
||||
app.use(urlencoded({ extended: true, limit: '50mb', parameterLimit: 1000000 }));
|
||||
app.useStaticAssets(join(__dirname, 'assets'), { prefix: (UrlPrefix ? UrlPrefix : '/') + 'assets' });
|
||||
app.enableVersioning({
|
||||
type: VersioningType.URI,
|
||||
defaultVersion: VERSION_NEUTRAL,
|
||||
});
|
||||
|
||||
setSecurityHeaders(app, configService);
|
||||
|
||||
const listen_addr = process.env.LISTEN_ADDR || '::';
|
||||
const port = parseInt(process.env.PORT) || 3000;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { ServeStaticModule } from '@nestjs/serve-static';
|
||||
import { join } from 'path';
|
||||
|
||||
const hasSubPath = process.env.SUB_PATH !== undefined;
|
||||
const UrlPrefix = hasSubPath ? process.env.SUB_PATH : '';
|
||||
|
||||
const imports = [
|
||||
ServeStaticModule.forRoot({
|
||||
rootPath: join(__dirname, 'assets'),
|
||||
serveRoot: (UrlPrefix ? UrlPrefix : '/../../../') + 'assets',
|
||||
})
|
||||
]
|
||||
|
||||
if (process.env.SERVE_CLIENT !== 'false' && process.env.NODE_ENV === 'production') {
|
||||
imports.unshift(
|
||||
ServeStaticModule.forRoot({
|
||||
// Have to remove trailing slash of SUB_PATH.
|
||||
serveRoot: process.env.SUB_PATH === undefined ? '' : process.env.SUB_PATH.replace(/\/$/, ''),
|
||||
rootPath: join(__dirname, '../../../../../', 'frontend/build'),
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
@Module({
|
||||
imports
|
||||
})
|
||||
|
||||
export class StaticFileServerModule {}
|
||||
Loading…
Reference in a new issue