690401:2223 fix double warp by cluade opus local work
This commit is contained in:
+2
-7
@@ -9,10 +9,6 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|||||||
import { json, urlencoded } from 'express';
|
import { json, urlencoded } from 'express';
|
||||||
import helmet from 'helmet';
|
import helmet from 'helmet';
|
||||||
|
|
||||||
// Import Custom Interceptors & Filters ที่สร้างใน T1.1
|
|
||||||
import { TransformInterceptor } from './common/interceptors/transform.interceptor';
|
|
||||||
import { HttpExceptionFilter } from './common/exceptions/http-exception.filter';
|
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
// 1. Create App
|
// 1. Create App
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
@@ -65,9 +61,8 @@ async function bootstrap() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
// ลงทะเบียน Global Interceptor และ Filter ที่เราสร้างไว้
|
// ⚠️ TransformInterceptor & HttpExceptionFilter ลงทะเบียนผ่าน APP_INTERCEPTOR/APP_FILTER ใน CommonModule แล้ว
|
||||||
app.useGlobalInterceptors(new TransformInterceptor());
|
// ห้ามลงทะเบียนซ้ำที่นี่ เพราะจะทำให้ Response ถูก wrap ซ้อน 2 ชั้น
|
||||||
app.useGlobalFilters(new HttpExceptionFilter());
|
|
||||||
|
|
||||||
// 📘 6. Swagger Configuration
|
// 📘 6. Swagger Configuration
|
||||||
const swaggerConfig = new DocumentBuilder()
|
const swaggerConfig = new DocumentBuilder()
|
||||||
|
|||||||
+49
-16
@@ -6,10 +6,45 @@ import { auth } from '@/lib/auth';
|
|||||||
// รายการ Route ที่ไม่ต้อง Login ก็เข้าได้ (Public Routes)
|
// รายการ Route ที่ไม่ต้อง Login ก็เข้าได้ (Public Routes)
|
||||||
const publicRoutes = ['/login', '/register', '/'];
|
const publicRoutes = ['/login', '/register', '/'];
|
||||||
|
|
||||||
|
// 🛡️ Bot/Scanner Patterns - บล็อก requests ที่เป็น automated scanning
|
||||||
|
const blockedPatterns = [
|
||||||
|
// WordPress scanning
|
||||||
|
/\/wp-includes/i,
|
||||||
|
/\/wp-content/i,
|
||||||
|
/\/wp\//i,
|
||||||
|
/\/wordpress/i,
|
||||||
|
/\/xmlrpc\.php/i,
|
||||||
|
/wlwmanifest\.xml/i,
|
||||||
|
// Environment/config files
|
||||||
|
/\/\.env/i,
|
||||||
|
/\/\.env\./i,
|
||||||
|
/\/config\/\.env/i,
|
||||||
|
/\/api\/\.env/i,
|
||||||
|
// Database admin tools
|
||||||
|
/\/phpmyadmin/i,
|
||||||
|
/\/adminer/i,
|
||||||
|
/\/pma/i,
|
||||||
|
// Common scanner paths
|
||||||
|
/\/\.git/i,
|
||||||
|
/\/\.svn/i,
|
||||||
|
/\/config\.json/i,
|
||||||
|
/\/package\.json/i,
|
||||||
|
];
|
||||||
|
|
||||||
|
function isBlockedPath(path: string): boolean {
|
||||||
|
return blockedPatterns.some((pattern) => pattern.test(path));
|
||||||
|
}
|
||||||
|
|
||||||
export default auth((req) => {
|
export default auth((req) => {
|
||||||
const isLoggedIn = !!req.auth;
|
|
||||||
const { nextUrl } = req;
|
const { nextUrl } = req;
|
||||||
|
|
||||||
|
// 🛡️ 0. Block Bot/Scanner Requests (ไม่ส่งต่อไป backend)
|
||||||
|
if (isBlockedPath(nextUrl.pathname)) {
|
||||||
|
return new NextResponse(null, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const isLoggedIn = !!req.auth;
|
||||||
|
|
||||||
const isPublicRoute = publicRoutes.includes(nextUrl.pathname);
|
const isPublicRoute = publicRoutes.includes(nextUrl.pathname);
|
||||||
const isAuthRoute = nextUrl.pathname.startsWith('/api/auth');
|
const isAuthRoute = nextUrl.pathname.startsWith('/api/auth');
|
||||||
|
|
||||||
@@ -56,21 +91,19 @@ export default auth((req) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cspHeader = `
|
const cspHeader = [
|
||||||
default-src 'self';
|
"default-src 'self'",
|
||||||
script-src 'self' 'nonce-${nonce}' 'strict-dynamic' 'unsafe-eval';
|
`script-src 'self' 'nonce-${nonce}' 'strict-dynamic' 'unsafe-eval' 'unsafe-inline' http: https:`,
|
||||||
style-src 'self' 'unsafe-inline';
|
"style-src 'self' 'unsafe-inline'",
|
||||||
img-src 'self' blob: data: https:;
|
"img-src 'self' blob: data: https:",
|
||||||
font-src 'self' data:;
|
"font-src 'self' data:",
|
||||||
connect-src 'self' ws: wss: ${connectSrcApi};
|
`connect-src 'self' ws: wss: ${connectSrcApi}`,
|
||||||
object-src 'none';
|
"object-src 'none'",
|
||||||
base-uri 'self';
|
"base-uri 'self'",
|
||||||
form-action 'self';
|
"form-action 'self'",
|
||||||
frame-ancestors 'none';
|
"frame-ancestors 'none'",
|
||||||
upgrade-insecure-requests;
|
"upgrade-insecure-requests",
|
||||||
`
|
].join('; ');
|
||||||
.replace(/\s{2,}/g, ' ')
|
|
||||||
.trim();
|
|
||||||
|
|
||||||
const requestHeaders = new Headers(req.headers);
|
const requestHeaders = new Headers(req.headers);
|
||||||
requestHeaders.set('x-nonce', nonce);
|
requestHeaders.set('x-nonce', nonce);
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 130 B |
@@ -1,6 +1,5 @@
|
|||||||
|
# Block all crawlers from accessing any part of the site
|
||||||
|
# This is an API/application server, not a content site
|
||||||
User-agent: *
|
User-agent: *
|
||||||
Disallow: /api/
|
Disallow: /
|
||||||
Allow: /
|
|
||||||
|
|
||||||
# Sitemap
|
|
||||||
# Sitemap: https://your-domain.com/sitemap.xml
|
|
||||||
|
|||||||
Reference in New Issue
Block a user