From 6af461a1982c627b97a3f06a6aa4b69eda5ae945 Mon Sep 17 00:00:00 2001 From: Kavyamanchanpally Date: Thu, 4 Jun 2026 14:14:18 +0530 Subject: [PATCH 1/2] fix: add loading spinner to ExportButton during export (#1912) --- src/components/ExportButton.tsx | 45 ++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/src/components/ExportButton.tsx b/src/components/ExportButton.tsx index 7102bd92e..f4698a159 100644 --- a/src/components/ExportButton.tsx +++ b/src/components/ExportButton.tsx @@ -709,10 +709,17 @@ export default function ExportButton() { aria-label="Export dashboard metrics as CSV" className="flex w-full items-center justify-center gap-2 rounded-lg border border-[var(--border)] bg-[var(--control)] px-4 py-2 text-sm font-medium text-[var(--card-foreground)] transition-all hover:border-[var(--accent)] disabled:opacity-50 sm:w-auto sm:min-w-[140px] hover:opacity-90 active:scale-95" > - - {isExportingCSV ? "Exporting..." : "Export CSV"} + {isExportingCSV ? ( + + + + +) : ( + +)} +{isExportingCSV ? "Exporting..." : "Export CSV"} ); From f4883bcc8a69cf4e9b25e6ae552715139e926674 Mon Sep 17 00:00:00 2001 From: Kavyamanchanpally Date: Sun, 7 Jun 2026 17:15:32 +0530 Subject: [PATCH 2/2] security(env): add build-time environment validation --- package-lock.json | 26 ++++++++++++++++++++++++++ package.json | 19 ++++++++++--------- scripts/validate-env.js | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 scripts/validate-env.js diff --git a/package-lock.json b/package-lock.json index 1d179019c..09ecc0011 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4859,6 +4859,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4872,6 +4873,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4885,6 +4887,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4898,6 +4901,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4911,6 +4915,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4924,6 +4929,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4937,6 +4943,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4950,6 +4957,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4963,6 +4971,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4976,6 +4985,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4989,6 +4999,7 @@ "cpu": [ "loong64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5002,6 +5013,7 @@ "cpu": [ "loong64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5015,6 +5027,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5028,6 +5041,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5041,6 +5055,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5054,6 +5069,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5067,6 +5083,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5080,6 +5097,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5093,6 +5111,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5106,6 +5125,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5119,6 +5139,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5132,6 +5153,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5145,6 +5167,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5158,6 +5181,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5171,6 +5195,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -16230,6 +16255,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, diff --git a/package.json b/package.json index b1726392f..2098aa94d 100644 --- a/package.json +++ b/package.json @@ -3,15 +3,16 @@ "version": "0.2.0", "private": true, "scripts": { - "dev": "next dev", - "build": "next build && node scripts/copy-standalone-static.js", - "start": "next start", - "lint": "next lint", - "type-check": "tsc --noEmit", - "test": "vitest run", - "test:e2e": "playwright test", - "supabase:generate-types": "npx supabase@latest gen types typescript --local > src/types/supabase.ts" - }, + "dev": "next dev", + "validate-env": "node scripts/validate-env.js", + "build": "npm run validate-env && next build && node scripts/copy-standalone-static.js", + "start": "next start", + "lint": "next lint", + "type-check": "tsc --noEmit", + "test": "vitest run", + "test:e2e": "playwright test", + "supabase:generate-types": "npx supabase@latest gen types typescript --local > src/types/supabase.ts" +}, "dependencies": { "@ducanh2912/next-pwa": "^10.2.9", "@supabase/ssr": "^0.10.3", diff --git a/scripts/validate-env.js b/scripts/validate-env.js new file mode 100644 index 000000000..5e09938e1 --- /dev/null +++ b/scripts/validate-env.js @@ -0,0 +1,34 @@ +const sensitivePatterns = [ + "private_key", + "secret", + "supabase_secret", + "github_token", + "token", + "password", + "api_key", + "apikey", +]; + +let hasErrors = false; + +console.log("šŸ” Validating environment variables..."); + +for (const key of Object.keys(process.env)) { + const lowerKey = key.toLowerCase(); + + const isSensitive = sensitivePatterns.some((pattern) => + lowerKey.includes(pattern) + ); + + if (isSensitive && !key.startsWith("NEXT_PUBLIC_")) { + console.error(`āŒ Sensitive environment variable detected: ${key}`); + hasErrors = true; + } +} + +if (hasErrors) { + console.error("\n🚨 Build blocked: Private credentials detected."); + process.exit(1); +} + +console.log("āœ… Environment validation passed."); \ No newline at end of file