@@ -6,13 +6,54 @@ import { ValidationPipe } from '@nestjs/common';
66async function bootstrap ( ) {
77 const app = await NestFactory . create ( AppModule ) ;
88
9- app . useGlobalPipes (
10- new ValidationPipe ( {
11- transform : true ,
12- } ) ,
13- ) ;
9+ const environment = process . env . NODE_ENV || 'development' ;
10+ const rawOrigins = process . env . WHITELISTED_ORIGINS || '' ;
11+ const rawTunnelDomains = process . env . TUNNEL_DOMAINS || '' ;
12+
13+ const whiteListedOrigins = rawOrigins
14+ . split ( ',' )
15+ . map ( ( origin ) => origin . trim ( ) . replace ( / ^ h t t p s ? : \/ \/ / , '' ) )
16+ . filter ( ( origin ) => ! ! origin ) ;
17+
18+ const tunnelDomains = rawTunnelDomains
19+ . split ( ',' )
20+ . map ( ( domain ) => domain . trim ( ) )
21+ . filter ( ( domain ) => ! ! domain ) ;
22+
23+ app . enableCors ( {
24+ origin : (
25+ origin : string | undefined ,
26+ callback : ( err : Error | null , allow ?: boolean ) => void ,
27+ ) => {
28+ if ( ! origin ) return callback ( null , true ) ;
29+
30+ try {
31+ const { hostname } = new URL ( origin ) ;
32+
33+ const isWhitelisted = whiteListedOrigins . includes ( hostname ) ;
34+
35+ const isTunnelDomain =
36+ environment !== 'production' &&
37+ tunnelDomains . some ( ( testDomain ) => hostname . endsWith ( testDomain ) ) ;
38+
39+ if ( isWhitelisted || isTunnelDomain ) {
40+ return callback ( null , true ) ;
41+ }
42+
43+ console . error ( `[CORS ERROR]: Origin ${ origin } is not allowed.` ) ;
44+ return callback ( new Error ( `CORS blocked for origin: ${ origin } ` ) ) ;
45+ } catch ( error ) {
46+ console . error ( `[CORS ERROR]: Malformed origin` , error ) ;
47+ return callback ( new Error ( `Invalid origin: ${ origin } ` ) ) ;
48+ }
49+ } ,
50+ credentials : true ,
51+ } ) ;
52+
53+ app . useGlobalPipes ( new ValidationPipe ( { transform : true } ) ) ;
1454 app . use ( cookieParser ( ) ) ;
1555
1656 await app . listen ( process . env . PORT ?? 3000 ) ;
1757}
58+
1859bootstrap ( ) ;
0 commit comments