Skip to content

Commit d08d932

Browse files
Sanitize secrets and env usage
- Remove hardcoded anon keys and project URLs scattered across codebase - Replace hardcoded URLs with environment variables - Delete vulnerable archived migration and align mcp-server with env-based config - Ensure all openapi/docs reflect env-based base URLs for production safety X-Lovable-Edit-ID: edt-ebbb96e9-1dd6-46de-8b45-fc8052bf2b04
2 parents 8bfd460 + 54949b9 commit d08d932

File tree

11 files changed

+22
-35
lines changed

11 files changed

+22
-35
lines changed

mcp-server/.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
SUPABASE_URL=https://vatgianzotsurljznsry.supabase.co
1+
SUPABASE_URL=https://your-project-id.supabase.co
22
SUPABASE_SERVICE_KEY=your-service-role-key-here
33

44
# Optional: Redis caching (Upstash)

mcp-server/src/utils/supabase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import { createClient, SupabaseClient } from "@supabase/supabase-js";
66

77
// Supabase configuration from environment
8-
const SUPABASE_URL = process.env.SUPABASE_URL || "https://vatgianzotsurljznsry.supabase.co";
8+
const SUPABASE_URL = process.env.SUPABASE_URL || "";
99
const SUPABASE_SERVICE_KEY = process.env.SUPABASE_SERVICE_KEY || "";
1010

1111
/**

public/openapi.json

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"openapi": "3.0.3",
33
"info": {
44
"title": "Eryxon Flow API",
5-
"description": "Production workflow management API for sheet metal manufacturing. This API allows you to manage jobs, parts, tasks, and track production progress through various stages.\n\n## Authentication\n\nAll API requests require an API key. Include your API key in the `Authorization` header:\n\n```\nAuthorization: Bearer ery_live_your_api_key_here\n```\n\n## Getting Started\n\n1. **Generate an API Key**: Navigate to Admin > API Keys in the web interface\n2. **Test the Connection**: Use the `/api-stages` endpoint (read-only) to verify your key works\n3. **Create Your First Job**: Use POST `/api-jobs` to create a job with parts and tasks\n4. **Track Progress**: Use GET endpoints to retrieve and monitor job status\n\n## Rate Limiting\n\nAPI requests are rate-limited based on your subscription plan:\n\n| Plan | Daily Limit |\n|------|-------------|\n| Free | 100 requests/day |\n| Pro | 1,000 requests/day |\n| Premium | 10,000 requests/day |\n| Enterprise | Unlimited |\n\nRate limit information is included in response headers:\n- `X-RateLimit-Remaining`: Remaining requests in current window\n- `X-RateLimit-Reset`: Timestamp when the limit resets\n- `Retry-After`: Seconds until you can retry (when rate limited)\n\nWhen you exceed your rate limit, you'll receive a `429 Too Many Requests` response.\n\n## Base URL\n\n```\nhttps://vatgianzotsurljznsry.supabase.co/functions/v1\n```",
5+
"description": "Production workflow management API for sheet metal manufacturing. This API allows you to manage jobs, parts, tasks, and track production progress through various stages.\n\n## Authentication\n\nAll API requests require an API key. Include your API key in the `Authorization` header:\n\n```\nAuthorization: Bearer ery_live_your_api_key_here\n```\n\n## Getting Started\n\n1. **Generate an API Key**: Navigate to Admin > API Keys in the web interface\n2. **Test the Connection**: Use the `/api-stages` endpoint (read-only) to verify your key works\n3. **Create Your First Job**: Use POST `/api-jobs` to create a job with parts and tasks\n4. **Track Progress**: Use GET endpoints to retrieve and monitor job status\n\n## Rate Limiting\n\nAPI requests are rate-limited based on your subscription plan:\n\n| Plan | Daily Limit |\n|------|-------------|\n| Free | 100 requests/day |\n| Pro | 1,000 requests/day |\n| Premium | 10,000 requests/day |\n| Enterprise | Unlimited |\n\nRate limit information is included in response headers:\n- `X-RateLimit-Remaining`: Remaining requests in current window\n- `X-RateLimit-Reset`: Timestamp when the limit resets\n- `Retry-After`: Seconds until you can retry (when rate limited)\n\nWhen you exceed your rate limit, you'll receive a `429 Too Many Requests` response.\n\n## Base URL\n\nThe base URL is your Supabase project URL followed by `/functions/v1`.",
66
"version": "1.0.0",
77
"contact": {
88
"name": "API Support",
@@ -11,8 +11,14 @@
1111
},
1212
"servers": [
1313
{
14-
"url": "https://vatgianzotsurljznsry.supabase.co/functions/v1",
15-
"description": "Production Server"
14+
"url": "{baseUrl}/functions/v1",
15+
"description": "Production Server",
16+
"variables": {
17+
"baseUrl": {
18+
"default": "https://your-project-id.supabase.co",
19+
"description": "Your Supabase project URL"
20+
}
21+
}
1622
}
1723
],
1824
"security": [

src/lib/event-dispatch.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ async function dispatchToWebhooks(
194194
return { success: false, error: 'Not authenticated' };
195195
}
196196

197-
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL || 'https://vatgianzotsurljznsry.supabase.co';
197+
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
198198

199199
const response = await fetch(
200200
`${supabaseUrl}/functions/v1/webhook-dispatch`,
@@ -242,7 +242,7 @@ async function dispatchToMqtt(
242242
return { success: false, error: 'Not authenticated' };
243243
}
244244

245-
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL || 'https://vatgianzotsurljznsry.supabase.co';
245+
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
246246

247247
const response = await fetch(
248248
`${supabaseUrl}/functions/v1/mqtt-publish`,

src/lib/mqtt-publishers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export async function triggerMqttPublish(
5252
return { success: false, error: 'Not authenticated' };
5353
}
5454

55-
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL || 'https://vatgianzotsurljznsry.supabase.co';
55+
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
5656

5757
const response = await fetch(
5858
`${supabaseUrl}/functions/v1/mqtt-publish`,

src/lib/webhooks.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ export async function triggerWebhook(
5050
return { success: false, error: 'Not authenticated' };
5151
}
5252

53-
// Get Supabase URL from environment or construct from current origin
54-
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL || 'https://vatgianzotsurljznsry.supabase.co';
53+
// Get Supabase URL from environment
54+
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
5555

5656
const response = await fetch(
5757
`${supabaseUrl}/functions/v1/webhook-dispatch`,

src/pages/admin/DataExport.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export default function DataExport() {
7272

7373
// Call export API
7474
const entities = selectedEntities.join(',');
75-
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL || 'https://vatgianzotsurljznsry.supabase.co';
75+
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
7676
const response = await fetch(
7777
`${supabaseUrl}/functions/v1/api-export?entities=${entities}&format=${exportFormat}`,
7878
{

src/pages/admin/DataImport.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ export default function DataImport() {
306306
if (!session) throw new Error('Not authenticated');
307307

308308
const transformedData = transformData();
309-
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL || 'https://vatgianzotsurljznsry.supabase.co';
309+
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
310310

311311
// Chunk data into batches of 100
312312
const BATCH_SIZE = 100;

src/pages/admin/config/ApiKeys.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ export default function ConfigApiKeys() {
7777
const { data: { session } } = await supabase.auth.getSession();
7878
if (!session) throw new Error('Not authenticated');
7979

80+
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
8081
const response = await fetch(
81-
`https://vatgianzotsurljznsry.supabase.co/functions/v1/api-key-generate`,
82+
`${supabaseUrl}/functions/v1/api-key-generate`,
8283
{
8384
method: 'POST',
8485
headers: {
@@ -386,7 +387,7 @@ export default function ConfigApiKeys() {
386387
<div className="flex-1">
387388
<p className="text-sm font-medium">Base URL</p>
388389
<code className="text-xs bg-muted px-2 py-1 rounded block break-all">
389-
https://vatgianzotsurljznsry.supabase.co/functions/v1
390+
{import.meta.env.VITE_SUPABASE_URL}/functions/v1
390391
</code>
391392
</div>
392393
</div>

src/pages/common/ApiDocs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import { useToast } from "@/hooks/use-toast";
3232
export default function ApiDocs() {
3333
const { toast } = useToast();
3434
const [apiKey, setApiKey] = useState("");
35-
const baseUrl = import.meta.env.VITE_SUPABASE_URL?.replace('/supabase', '') || "https://vatgianzotsurljznsry.supabase.co";
35+
const baseUrl = import.meta.env.VITE_SUPABASE_URL?.replace('/supabase', '') || "";
3636
const apiBaseUrl = `${baseUrl}/functions/v1`;
3737

3838
const copyToClipboard = (text: string, label: string) => {

0 commit comments

Comments
 (0)