This document outlines the comprehensive authentication and security improvements made to the MeshHook application to address the following issues:
- Database Schema: Fixed missing
workflowstable/view - Authentication Security: Replaced insecure
getSession()calls with securegetUser() - Server-Side Only: All Supabase calls now happen server-side with HTTP-only cookies
- Route Protection: Added authentication guards to all protected routes
- API Security: All API endpoints now require authentication and return 401 if unauthorized
File: supabase/migrations/20250110000005_create_workflows_view.sql
Created a view to map workflow_definitions table to workflows for backward compatibility:
create or replace view public.workflows as
select
id,
project_id,
slug,
version,
definition,
created_at,
updated_at
from public.workflow_definitions;File: apps/web/src/lib/auth.js (NEW)
Created a comprehensive authentication utility library with the following functions:
requireAuth(event)- Redirects to /auth/login if not authenticated (for page routes)getUser(event)- Returns user or null without redirectingisAuthenticated(event)- Boolean check for authenticationgetSupabase(event)- Gets Supabase client from event.localsrequireApiAuth(event)- Returns 401 JSON response if not authenticated (for API routes)verifyProjectAccess(supabase, userId, projectId)- Verifies user has access to a project
File: apps/web/src/hooks.server.js
Updated to:
- Use
supabase.auth.getUser()instead ofgetSession()for security - Make user and supabase client available via
event.locals - Run authentication check on every request
Updated the following page server files to use requireAuth():
apps/web/src/routes/workflows/+page.server.jsapps/web/src/routes/secrets/+page.server.jsapps/web/src/routes/runs/+page.server.js
Pattern used:
import { requireAuth, getSupabase } from '$lib/auth.js';
export async function load(event) {
const user = requireAuth(event); // Redirects to /auth/auth/login if not authenticated
const supabase = getSupabase(event);
// ... rest of the code
}Updated the following API routes to check authentication:
apps/web/src/routes/api/secrets/+server.jsapps/web/src/routes/api/secrets/[id]/+server.js
Pattern used:
import { getUser, getSupabase } from '$lib/auth.js';
import { json } from '@sveltejs/kit';
export async function GET(event) {
const user = getUser(event);
if (!user) {
return json({
error: 'Unauthorized',
message: 'Authentication required'
}, { status: 401 });
}
const supabase = getSupabase(event);
// ... rest of the code
}- ❌ Used
supabase.auth.getSession()which reads from storage (insecure) - ❌ Client-side Supabase calls exposed credentials
- ❌ No authentication guards on routes
- ❌ API routes didn't verify authentication
- ❌ Missing database table caused errors
- ✅ Uses
supabase.auth.getUser()which verifies with Supabase Auth server - ✅ All Supabase calls happen server-side only
- ✅ HTTP-only cookies for session management
- ✅ All protected routes redirect to /auth/login if not authenticated
- ✅ All API routes return 401 if not authenticated
- ✅ Database schema fixed with workflows view
The following files still contain getSession() calls and should be updated using the same patterns:
apps/web/src/routes/+layout.server.jsapps/web/src/routes/workflows/[id]/edit/+page.server.jsapps/web/src/routes/runs/[id]/+page.server.js
apps/web/src/routes/api/workflows/+server.jsapps/web/src/routes/api/workflows/[id]/+server.jsapps/web/src/routes/api/workflows/[id]/versions/+server.jsapps/web/src/routes/api/runs/+server.js
# If using Supabase CLI
supabase db push
# Or apply manually via Supabase Dashboard
# SQL Editor -> New Query -> Paste contents of 20250110000005_create_workflows_view.sql-
Unauthenticated Access:
- Visit
/workflowswithout being logged in - Should redirect to
/auth/login - Same for
/secretsand/runs
- Visit
-
API Authentication:
# Should return 401 curl http://localhost:5173/api/secrets # With valid session cookie should return data curl -H "Cookie: sb-access-token=..." http://localhost:5173/api/secrets
-
Authenticated Access:
- Log in via
/auth/login - Visit
/workflows,/secrets,/runs - Should load data successfully
- No console warnings about
getSession()
- Log in via
Check browser console and server logs for:
- ❌ No warnings about "Using the user object as returned from supabase.auth.getSession()"
- ❌ No errors about missing
workflowstable - ✅ Clean logs with no authentication warnings
- Apply database migration to production
- Deploy updated application code
- Verify environment variables are set correctly
- Test authentication flow in production
- Monitor logs for any authentication errors
- Update remaining files with
getSession()calls
- Add Login/Logout Routes: Create proper login and logout pages if they don't exist
- Session Management: Consider adding session refresh logic
- Error Pages: Create a proper 401/403 error page
- Rate Limiting: Add rate limiting to API routes
- CSRF Protection: Consider adding CSRF tokens for state-changing operations
- Audit Logging: Log all authentication attempts and failures
For issues or questions about these changes, refer to:
- Supabase Auth documentation: https://supabase.com/docs/guides/auth
- SvelteKit hooks documentation: https://kit.svelte.dev/docs/hooks