refactor: enhance security and performance in configuration and API routes

- Update Content Security Policy (CSP) in next.config.ts to avoid `unsafe-eval` in production, improving security against XSS attacks.
- Refactor API routes to enforce admin authentication and session validation, ensuring secure access to sensitive endpoints.
- Optimize analytics data retrieval by using database aggregation instead of loading all records into memory, improving performance and reducing memory usage.
- Implement session token creation and verification for better session management and security across the application.
- Enhance error handling and input validation in various API routes to ensure robustness and prevent potential issues.
This commit is contained in:
2026-01-11 22:44:26 +01:00
parent 9cc03bc475
commit 9072faae43
28 changed files with 433 additions and 288 deletions

View File

@@ -37,7 +37,13 @@ export async function POST(request: NextRequest) {
}
// Get admin credentials from environment
const adminAuth = process.env.ADMIN_BASIC_AUTH || 'admin:default_password_change_me';
const adminAuth = process.env.ADMIN_BASIC_AUTH;
if (!adminAuth || adminAuth.trim() === '' || adminAuth === 'admin:default_password_change_me') {
return new NextResponse(
JSON.stringify({ error: 'Admin auth is not configured' }),
{ status: 503, headers: { 'Content-Type': 'application/json' } }
);
}
const [, expectedPassword] = adminAuth.split(':');
// Secure password comparison using constant-time comparison
@@ -48,22 +54,14 @@ export async function POST(request: NextRequest) {
// Use constant-time comparison to prevent timing attacks
if (passwordBuffer.length === expectedBuffer.length &&
crypto.timingSafeEqual(passwordBuffer, expectedBuffer)) {
// Generate cryptographically secure session token
const timestamp = Date.now();
const randomBytes = crypto.randomBytes(32);
const randomString = randomBytes.toString('hex');
// Create session data
const sessionData = {
timestamp,
random: randomString,
ip: ip,
userAgent: request.headers.get('user-agent') || 'unknown'
};
// Encode session data (base64 is sufficient for this use case)
const sessionJson = JSON.stringify(sessionData);
const sessionToken = Buffer.from(sessionJson).toString('base64');
const { createSessionToken } = await import('@/lib/auth');
const sessionToken = createSessionToken(request);
if (!sessionToken) {
return new NextResponse(
JSON.stringify({ error: 'Session secret not configured' }),
{ status: 503, headers: { 'Content-Type': 'application/json' } }
);
}
return new NextResponse(
JSON.stringify({