Skip to content

Commit f063715

Browse files
committed
chore: secure GitHub Pages deploy and harden client secret handling
- add GitHub Pages workflow - add gitleaks workflow to scan pushes/PRs for leaked secrets - remove client-side logs that exposed env/session/debug info - document secure GitHub Pages + Supabase setup in README
1 parent ce60bb0 commit f063715

11 files changed

Lines changed: 157 additions & 48 deletions

File tree

.github/workflows/deploy-pages.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Deploy to GitHub Pages
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: pages
15+
cancel-in-progress: true
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Pages
25+
id: pages
26+
uses: actions/configure-pages@v5
27+
28+
- name: Setup Node
29+
uses: actions/setup-node@v4
30+
with:
31+
node-version: 20
32+
cache: npm
33+
34+
- name: Install dependencies
35+
run: npm ci
36+
37+
- name: Build
38+
run: npm run build -- --base "${{ steps.pages.outputs.base_path }}"
39+
env:
40+
VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }}
41+
VITE_SUPABASE_ANON_KEY: ${{ secrets.VITE_SUPABASE_ANON_KEY }}
42+
43+
- name: SPA fallback for direct route loads
44+
run: cp dist/index.html dist/404.html
45+
46+
- name: Upload Pages artifact
47+
uses: actions/upload-pages-artifact@v3
48+
with:
49+
path: dist
50+
51+
deploy:
52+
environment:
53+
name: github-pages
54+
url: ${{ steps.deployment.outputs.page_url }}
55+
runs-on: ubuntu-latest
56+
needs: build
57+
steps:
58+
- name: Deploy to GitHub Pages
59+
id: deployment
60+
uses: actions/deploy-pages@v4

.github/workflows/secret-scan.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Secret Scan
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: ["main"]
7+
workflow_dispatch:
8+
9+
jobs:
10+
gitleaks:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v4
15+
with:
16+
fetch-depth: 0
17+
18+
- name: Run Gitleaks
19+
uses: gitleaks/gitleaks-action@v2
20+
env:
21+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

README.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ A web application for mapping and visualizing data using Supabase and React.
1919
- [Schema Overview](#schema-overview)
2020
- [Quick Start](#quick-start)
2121
- [Backend Mode: Local vs Online](#backend-mode-local-vs-online)
22+
- [GitHub Pages Deployment](#github-pages-deployment)
2223
- [Database Management](#database-management)
2324
- [Development Commands](#development-commands)
2425
- [Dev Tips](#dev-tips)
@@ -99,12 +100,14 @@ Best for: Production, staging, or if you don't want to run Docker locally.
99100

100101
5. **Seed test data** (optional):
101102
- Go to **Authentication****Users****Add User**
102-
- Create a user with email `test@gmail.com` and password `password`
103+
- Create a user with your own email and a strong password
104+
- In `supabase/seed_data.sql`, set `target_email` to that email
103105
- Go to **SQL Editor** and run the contents of `supabase/seed_data.sql`
104-
- The script automatically finds the test user and creates:
106+
- The script creates:
105107
- **Testimony** project
106108
- **Pink Line** project
107-
- Adds the test user as an editor to both projects
109+
- **Memorial Sites** project
110+
- Adds your selected user as an editor to all projects
108111

109112
### Option B: Local Mode (Supabase Local)
110113

@@ -135,30 +138,36 @@ Local mode runs Supabase services in Docker containers on your machine.
135138
supabase db reset
136139
```
137140

138-
This creates a test user and project automatically.
141+
This creates a local-only test user and project automatically.
142+
143+
## GitHub Pages Deployment
144+
145+
This repo includes a GitHub Pages workflow at `.github/workflows/deploy-pages.yml`.
139146

140147
## Database Management
141148

142149
### Test User Credentials
143150

144-
The seed file creates a test user you can use immediately (both local and cloud):
151+
`supabase/seed.sql` creates a local development test user:
145152

146153
| Field | Value |
147154
| -------- | ---------------- |
148155
| Email | `test@gmail.com` |
149156
| Password | `password` |
150157

151-
**Local mode**: This user is automatically added as owner of a "Test Project" when you run `supabase db reset`.
158+
**Local mode only**: This user is automatically added as owner of a "Test Project" when you run `supabase db reset`.
152159

153-
**Cloud mode**: After creating the user via Dashboard, run `supabase/seed_data.sql` to add the user as an editor to "Testimony" and "Pink Line" projects.
160+
**Cloud mode**: Do not use shared demo credentials. Create a user with your own email and strong password, set `target_email` in `supabase/seed_data.sql`, then run it.
154161

155162
### Database Reset (Cloud)
156163

157164
If you need to completely reset your cloud database:
158165

159166
1. Go to **SQL Editor** in your Supabase dashboard
160167
2. Run `supabase/nuclear_reset.sql` to drop everything and recreate the schema
161-
3. Run `supabase/seed_data.sql` to add test data (after creating the test user)
168+
3. Create a real user in Auth (your email + strong password)
169+
4. Set `target_email` in `supabase/seed_data.sql`
170+
5. Run `supabase/seed_data.sql` to add project data and memberships
162171

163172
### Applying Migrations
164173

src/config.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
if (!import.meta.env.VITE_SUPABASE_ANON_KEY) {
2-
alert("VITE_SUPABASE_ANON_KEY is required");
3-
throw new Error("VITE_SUPABASE_ANON_KEY is required");
4-
}
5-
if (!import.meta.env.VITE_SUPABASE_URL) {
6-
alert("VITE_SUPABASE_URL is required");
7-
throw new Error("VITE_SUPABASE_URL is required");
1+
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
2+
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
3+
4+
if (!supabaseAnonKey || !supabaseUrl) {
5+
throw new Error("Missing required application configuration.");
86
}
97

10-
console.log(import.meta.env.VITE_SUPABASE_ANON_KEY);
11-
console.log(import.meta.env.VITE_SUPABASE_URL);
12-
export const SUPABASE_ANON_KEY = import.meta.env.VITE_SUPABASE_ANON_KEY;
13-
export const SUPABASE_URL = import.meta.env.VITE_SUPABASE_URL;
8+
export const SUPABASE_ANON_KEY = supabaseAnonKey;
9+
export const SUPABASE_URL = supabaseUrl;

src/pages/HomePage.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ const HomePage = () => {
1010
const navigate = useNavigate();
1111

1212
useEffect(() => {
13-
console.log("Current User:", session || "None");
1413
if (session) {
1514
navigate("/projects-page");
1615
}

src/pages/MapPage/PinkLineMapPage.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ const PinkLineMapPage = () => {
4444
try { map.removeLayer(routeLineRef.current); } catch (_) { /* already gone */ }
4545
routeLineRef.current = null;
4646
}
47-
console.log(`[PinkLine] Cleared ${count} route layers`);
4847
};
4948

5049
useEffect(() => {
@@ -126,7 +125,6 @@ const PinkLineMapPage = () => {
126125
.then((geojson: GeoJSON.FeatureCollection) => {
127126
if (!mapRef.current) return;
128127
defaultLinePathsRef.current = parseDefaultLinePaths(geojson);
129-
console.log(`[PinkLine] Base line loaded: ${defaultLinePathsRef.current.length} paths`);
130128
setDefaultLineLoaded(true);
131129
})
132130
.catch((err) => console.error("Failed to load default pink line:", err));
@@ -179,8 +177,6 @@ const PinkLineMapPage = () => {
179177
if (hasBase) {
180178
const userPoints = nodes.map((n) => [n.lat, n.lng] as [number, number]);
181179
const { solid, dashed } = buildIntegratedRoute(basePaths, userPoints);
182-
console.log(`[PinkLine] Rendering ${solid.length} solid + ${dashed.length} dashed segments for ${nodes.length} nodes`);
183-
184180
const solidStyle: L.PolylineOptions = { color: "#FF69B4", weight: 5, opacity: 0.9 };
185181
const dashedStyle: L.PolylineOptions = { color: "#FF69B4", weight: 5, opacity: 0.9, dashArray: "10, 10" };
186182

src/pages/ProjectsPage.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ const ProjectsPage = () => {
2424
await ensureMemorialSitesProjectForUser(user.id);
2525
}
2626
const data = await loadProjects();
27-
console.log("Loaded projects:", data);
2827
setProjects(data || []);
2928
} catch (err) {
3029
setError(err.message);

src/supabase/features.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ export async function updateGeometry(id: number, geom: GeoJSON) {
5555
}
5656

5757
export async function deleteGeometry(id: number) {
58-
console.log("Deleting geometry with ID:", id);
5958
const { error } = await supabase.from("geo_features").delete().eq("id", id);
6059
if (error) throw error;
6160
}

supabase/seed.cloud.sql

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,38 @@
33
--
44
-- BEFORE RUNNING THIS:
55
-- 1. Go to Authentication → Users → Add User
6-
-- 2. Create user with email: test@gmail.com, password: password
7-
-- 3. The script will automatically find the user by email
6+
-- 2. Create a real user with your own email + strong password
7+
-- 3. Set target_email below to that user's email
8+
-- 4. Do not use shared test credentials in cloud environments
89

910
DO $$
1011
DECLARE
12+
target_email text := 'CHANGE_ME_EMAIL@example.com';
1113
test_user_id uuid;
1214
BEGIN
13-
-- Find test user by email
15+
IF target_email = 'CHANGE_ME_EMAIL@example.com' THEN
16+
RAISE EXCEPTION 'Set target_email in supabase/seed.cloud.sql before running this script';
17+
END IF;
18+
19+
-- Find user by email
1420
SELECT id INTO test_user_id
1521
FROM auth.users
16-
WHERE email = 'test@gmail.com'
22+
WHERE lower(email) = lower(target_email)
1723
LIMIT 1;
1824

1925
IF test_user_id IS NULL THEN
20-
RAISE EXCEPTION 'Test user not found. Please create user with email test@gmail.com via Dashboard first';
26+
RAISE EXCEPTION 'User not found. Please create user with email % via Dashboard first', target_email;
2127
END IF;
28+
-- Create Memorial Sites project
29+
INSERT INTO public.projects (id, name, description, created_at)
30+
VALUES (
31+
'33333333-3333-3333-3333-333333333333',
32+
'Memorial Sites',
33+
'אתרי הנצחה',
34+
now()
35+
)
36+
ON CONFLICT (id) DO NOTHING;
37+
2238

2339
-- Create Testimony project
2440
INSERT INTO public.projects (id, name, description, created_at)
@@ -40,7 +56,7 @@ BEGIN
4056
)
4157
ON CONFLICT (id) DO NOTHING;
4258

43-
-- Add test user as editor to Testimony project
59+
-- Add target user as editor to Testimony project
4460
INSERT INTO public.project_members (project_id, user_id, role)
4561
VALUES (
4662
'11111111-1111-1111-1111-111111111111',
@@ -49,7 +65,7 @@ BEGIN
4965
)
5066
ON CONFLICT (project_id, user_id) DO UPDATE SET role = 'editor';
5167

52-
-- Add test user as editor to Pink Line project
68+
-- Add target user as editor to Pink Line project
5369
INSERT INTO public.project_members (project_id, user_id, role)
5470
VALUES (
5571
'22222222-2222-2222-2222-222222222222',
@@ -58,5 +74,14 @@ BEGIN
5874
)
5975
ON CONFLICT (project_id, user_id) DO UPDATE SET role = 'editor';
6076

61-
RAISE NOTICE 'Seed data created successfully. Test user ID: %', test_user_id;
77+
-- Add target user as editor to Memorial Sites project
78+
INSERT INTO public.project_members (project_id, user_id, role)
79+
VALUES (
80+
'33333333-3333-3333-3333-333333333333',
81+
test_user_id,
82+
'editor'
83+
)
84+
ON CONFLICT (project_id, user_id) DO UPDATE SET role = 'editor';
85+
86+
RAISE NOTICE 'Seed data created successfully. User ID: %', test_user_id;
6287
END $$;

supabase/seed.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
-- Local development seed file
22
-- Usage: supabase db reset (runs migrations + seed automatically)
3+
-- NOTE: This file is for local development only. Do not use these credentials in cloud/prod.
34
--
45
-- Test user credentials:
56
-- Email: test@gmail.com

0 commit comments

Comments
 (0)