diff --git a/src/app.ts b/src/app.ts index 9ab599a..9bd6207 100644 --- a/src/app.ts +++ b/src/app.ts @@ -11,11 +11,12 @@ import config from './config/config'; import authLimiter from './middleware/authLimiter'; import { xssMiddleware } from './middleware/xssMiddleware'; import path from 'path'; +import corsConfig from './config/cors'; const app: Express = express(); // Helmet is used to secure this app by configuring the http-header -app.use(helmet()); +app.use(helmet.frameguard({ action: 'deny' })); // parse json request body app.use(express.json()); @@ -30,13 +31,7 @@ app.use(cookieParser()); // Compression is used to reduce the size of the response body app.use(compression({ filter: compressFilter })); -app.use( - cors({ - // origin is given a array if we want to have multiple origins later - origin: String(config.cors.cors_origin).split('|'), - credentials: true - }) -); +app.use(cors(corsConfig)); if (config.node_env === 'production') { app.use('/api/v1/auth', authLimiter); diff --git a/src/config/cors.ts b/src/config/cors.ts new file mode 100644 index 0000000..6849438 --- /dev/null +++ b/src/config/cors.ts @@ -0,0 +1,33 @@ +import { type CorsOptions } from 'cors'; +import config from './config'; + +const whitelist = String(config.cors.cors_origin).split('|') ?? []; + +const corsConfig: Readonly = { + origin ( + origin: string | undefined, + callback: ( + err: Error | null, + origin?: boolean | string | RegExp | Array + ) => void + ) { + if (!origin || whitelist.some((val) => origin.match(val))) { + callback(null, true); + } else { + callback(new Error('Not allowed by CORS')); + } + }, + maxAge: 86400, + headers: [ + 'Accept', + 'Authorization', + 'Content-Type', + 'If-None-Match', + 'BX-User-Token', + 'Trace-Id' + ], + exposedHeaders: ['WWW-Authenticate', 'Server-Authorization'], + credentials: true +} as CorsOptions; + +export default corsConfig;