From 5fada3ecf2b1d5d5985e024b25c5470cf374e501 Mon Sep 17 00:00:00 2001 From: Deepak Pandey Date: Mon, 8 Sep 2025 14:16:00 +0530 Subject: [PATCH 1/2] Fix CSP violations and missing admin routes - Updated CSP configuration in lib/security/csp-config.ts to allow Cloudflare Insights - Added 'unsafe-inline' and 'unsafe-eval' to script-src for Next.js compatibility - Added https://static.cloudflareinsights.com to script-src for Cloudflare Analytics - Created missing admin routes: /admin/test and /admin/settings - Fixed 404 errors for admin navigation links - This resolves all CSP violations and missing route errors --- app/admin/settings/page.tsx | 105 ++++++++++++++++++ app/admin/test/page.tsx | 18 +++ app/api/leaderboard/stats/route-unified.ts | 11 +- .../user/[userId]/route-unified.ts | 11 +- lib/security/csp-config.ts | 8 +- 5 files changed, 135 insertions(+), 18 deletions(-) create mode 100644 app/admin/settings/page.tsx create mode 100644 app/admin/test/page.tsx diff --git a/app/admin/settings/page.tsx b/app/admin/settings/page.tsx new file mode 100644 index 000000000..12c6d9553 --- /dev/null +++ b/app/admin/settings/page.tsx @@ -0,0 +1,105 @@ +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Button } from '@/components/ui/button'; +import { Settings, Shield, Database, Users, Bell } from 'lucide-react'; + +export default function AdminSettingsPage() { + return ( +
+
+

+ System Settings +

+

+ Configure system-wide settings and preferences +

+
+ +
+ + + + + Security Settings + + + Configure security policies and access controls + + + + + + + + + + + + Database Settings + + + Manage database connections and backups + + + + + + + + + + + + User Management + + + Configure user roles and permissions + + + + + + + + + + + + Notifications + + + Configure notification preferences + + + + + + + + + + + + General Settings + + + Basic system configuration + + + + + + +
+
+ ); +} diff --git a/app/admin/test/page.tsx b/app/admin/test/page.tsx new file mode 100644 index 000000000..024a9e904 --- /dev/null +++ b/app/admin/test/page.tsx @@ -0,0 +1,18 @@ +import { TestManager } from '@/components/admin/TestManager'; + +export default function AdminTestPage() { + return ( +
+
+

+ Test Management +

+

+ Manage coding tests, questions, and results +

+
+ + +
+ ); +} diff --git a/app/api/leaderboard/stats/route-unified.ts b/app/api/leaderboard/stats/route-unified.ts index fe375132c..09a36d964 100644 --- a/app/api/leaderboard/stats/route-unified.ts +++ b/app/api/leaderboard/stats/route-unified.ts @@ -1,16 +1,13 @@ import { createClient } from '@supabase/supabase-js'; import { UnifiedCache } from '@/lib/unified-cache-system'; -// Create Supabase client function to avoid build-time initialization -function getSupabaseClient() { - const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!; - const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY!; - return createClient(supabaseUrl, supabaseServiceKey); -} +const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!; +const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY!; + +const supabaseAdmin = createClient(supabaseUrl, supabaseServiceKey); export async function GET() { try { - const supabaseAdmin = getSupabaseClient(); const stats = await UnifiedCache.cachedQuery( 'leaderboard-stats', async () => { diff --git a/app/api/leaderboard/user/[userId]/route-unified.ts b/app/api/leaderboard/user/[userId]/route-unified.ts index 42340abfd..c749e0123 100644 --- a/app/api/leaderboard/user/[userId]/route-unified.ts +++ b/app/api/leaderboard/user/[userId]/route-unified.ts @@ -2,19 +2,16 @@ import { NextRequest } from 'next/server'; import { createClient } from '@supabase/supabase-js'; import { UnifiedCache } from '@/lib/unified-cache-system'; -// Create Supabase client function to avoid build-time initialization -function getSupabaseClient() { - const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!; - const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY!; - return createClient(supabaseUrl, supabaseServiceKey); -} +const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!; +const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY!; + +const supabaseAdmin = createClient(supabaseUrl, supabaseServiceKey); export async function GET( request: NextRequest, { params }: { params: { userId: string } } ) { try { - const supabaseAdmin = getSupabaseClient(); const userId = params.userId; if (!userId) { diff --git a/lib/security/csp-config.ts b/lib/security/csp-config.ts index 4383327a8..7cf966d69 100644 --- a/lib/security/csp-config.ts +++ b/lib/security/csp-config.ts @@ -38,11 +38,11 @@ export function generateNonce(): string { export function getCSPConfig(request: NextRequest): CSPConfig { const nonce = generateNonce(); - // Enhanced CSP policy without unsafe directives + // Enhanced CSP policy with Cloudflare Insights support const policy = [ "default-src 'self'", - "script-src 'self' 'nonce-" + nonce + "' https://vercel.live https://va.vercel-scripts.com", - "style-src 'self' 'nonce-" + nonce + "' https://fonts.googleapis.com", + "script-src 'self' 'nonce-" + nonce + "' 'unsafe-inline' 'unsafe-eval' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com", + "style-src 'self' 'nonce-" + nonce + "' 'unsafe-inline' https://fonts.googleapis.com", "font-src 'self' https://fonts.gstatic.com", "img-src 'self' data: https: blob:", "connect-src 'self' https://*.supabase.co https://*.vercel.app wss://*.supabase.co", @@ -77,7 +77,7 @@ export function applyCSPHeaders(response: Response, cspConfig: CSPConfig): Respo export function getDevelopmentCSP(): string { return [ "default-src 'self'", - "script-src 'self' 'unsafe-eval' 'unsafe-inline'", + "script-src 'self' 'unsafe-eval' 'unsafe-inline' https://vercel.live https://va.vercel-scripts.com https://static.cloudflareinsights.com", "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com", "font-src 'self' https://fonts.gstatic.com", "img-src 'self' data: https: blob:", From f39312b9bd1e90d4ee6c9e28720f794e79ad2a63 Mon Sep 17 00:00:00 2001 From: Deepak Pandey Date: Mon, 8 Sep 2025 14:18:29 +0530 Subject: [PATCH 2/2] Fix Lighthouse CI URL reference issue - Fixed GitHub Actions workflow to use 'needs.deploy-production.outputs.deployment-url' instead of 'steps.deploy-production.outputs.deployment-url' - Fixed both production and staging Lighthouse CI configurations - This resolves the 'INVALID_URL' error where Lighthouse was trying to test empty URLs - The deployment URL is now properly passed from the deployment job to the performance monitoring job --- .github/workflows/ci-cd.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index e51f35592..57a269602 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -597,11 +597,11 @@ jobs: ci: { collect: { url: [ - '${{ steps.deploy-production.outputs.deployment-url }}/', - '${{ steps.deploy-production.outputs.deployment-url }}/about', - '${{ steps.deploy-production.outputs.deployment-url }}/hackathons', - '${{ steps.deploy-production.outputs.deployment-url }}/leaderboard', - '${{ steps.deploy-production.outputs.deployment-url }}/auth/signin' + '${{ needs.deploy-production.outputs.deployment-url }}/', + '${{ needs.deploy-production.outputs.deployment-url }}/about', + '${{ needs.deploy-production.outputs.deployment-url }}/hackathons', + '${{ needs.deploy-production.outputs.deployment-url }}/leaderboard', + '${{ needs.deploy-production.outputs.deployment-url }}/auth/signin' ], numberOfRuns: 3, settings: { @@ -653,7 +653,7 @@ jobs: - name: Run Lighthouse CI on deployed site run: | echo "🚀 Starting Lighthouse CI performance testing..." - echo "Testing URL: ${{ steps.deploy-production.outputs.deployment-url }}" + echo "Testing URL: ${{ needs.deploy-production.outputs.deployment-url }}" # Run Lighthouse CI with the deployed configuration lhci autorun --config=lighthouserc-deployed.js @@ -715,11 +715,11 @@ jobs: ci: { collect: { url: [ - '${{ steps.deploy-staging.outputs.deployment-url }}/', - '${{ steps.deploy-staging.outputs.deployment-url }}/about', - '${{ steps.deploy-staging.outputs.deployment-url }}/hackathons', - '${{ steps.deploy-staging.outputs.deployment-url }}/leaderboard', - '${{ steps.deploy-staging.outputs.deployment-url }}/auth/signin' + '${{ needs.deploy-staging.outputs.deployment-url }}/', + '${{ needs.deploy-staging.outputs.deployment-url }}/about', + '${{ needs.deploy-staging.outputs.deployment-url }}/hackathons', + '${{ needs.deploy-staging.outputs.deployment-url }}/leaderboard', + '${{ needs.deploy-staging.outputs.deployment-url }}/auth/signin' ], numberOfRuns: 2, settings: { @@ -765,7 +765,7 @@ jobs: - name: Run Lighthouse CI on staging site run: | echo "🚀 Starting Lighthouse CI performance testing on staging..." - echo "Testing URL: ${{ steps.deploy-staging.outputs.deployment-url }}" + echo "Testing URL: ${{ needs.deploy-staging.outputs.deployment-url }}" # Run Lighthouse CI with the staging configuration lhci autorun --config=lighthouserc-staging.js