diff --git a/.cloudflared/config.yml b/.cloudflared/config.yml new file mode 100644 index 00000000..fdaaf285 --- /dev/null +++ b/.cloudflared/config.yml @@ -0,0 +1,18 @@ +# Cloudflare Tunnel Configuration +# This configures a named tunnel for development access via tunnel.cambeerfestival.app +# +# Setup instructions: +# 1. Login to Cloudflare: cloudflared tunnel login +# 2. Create the tunnel: cloudflared tunnel create cbf-dev-tunnel +# 3. Route DNS: cloudflared tunnel route dns cbf-dev-tunnel tunnel.cambeerfestival.app +# 4. Run the tunnel: cloudflared tunnel run cbf-dev-tunnel +# +# The tunnel UUID and credentials will be stored in ~/.cloudflared/ after creation + +tunnel: cbf-dev-tunnel +credentials-file: /home/vscode/.cloudflared/be8d5634-735e-4637-b030-6f818e739b77.json + +ingress: + - hostname: tunnel.cambeerfestival.app + service: http://localhost:8080 + - service: http_status:404 diff --git a/.gitignore b/.gitignore index 8c855efb..ba5670e2 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,10 @@ mise.local.toml mise.*.local.toml +# Cloudflare Tunnel +.cloudflared/*.json +.cloudflared/cert.pem + # Flutter repo-specific /bin/cache/ /bin/internal/bootstrap.bat diff --git a/cloudflare-worker/worker.js b/cloudflare-worker/worker.js index 9a4b0339..537120c8 100644 --- a/cloudflare-worker/worker.js +++ b/cloudflare-worker/worker.js @@ -23,6 +23,7 @@ const ALLOWED_ORIGINS = [ 'https://richardthe3rd.github.io', 'https://cambeerfestival.app', 'https://staging.cambeerfestival.app', + 'https://tunnel.cambeerfestival.app', 'http://localhost:8080', 'http://localhost:3000', 'http://127.0.0.1:8080', @@ -236,6 +237,17 @@ function getCorsHeaders(request) { }; } + // Allow Cloudflare Tunnel quick tunnels (*.trycloudflare.com) + // Used for local development with cloudflared tunnel + // Security note: These are temporary development tunnels controlled by Cloudflare. + // Only enable this in development/staging workers, not production. + if (origin.endsWith('.trycloudflare.com')) { + return { + 'Access-Control-Allow-Origin': origin, + 'Access-Control-Allow-Credentials': 'true', + }; + } + // Reject all other origins by not including CORS headers return {}; } diff --git a/mise.dev.toml b/mise.dev.toml index 9dc7ff42..611500b4 100644 --- a/mise.dev.toml +++ b/mise.dev.toml @@ -18,4 +18,75 @@ url = "https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d [macos-x64] url = "https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases/{version}/darwin-x64/claude" """, version_list_url = "https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases/stable" } +cloudflared = "latest" "npm:firebase-tools" = "14.26.0" # Pin to a stable version for reproducibility + +[tasks.dev] +run = ''' +echo "Starting Flutter dev server on http://localhost:8080" +flutter run -d web-server --web-port 8080 +''' + +[tasks.tunnel-setup] +run = ''' +echo "Setting up Cloudflare Tunnel for tunnel.cambeerfestival.app" +echo "" + +# Check if already logged in +if [ ! -f ~/.cloudflared/cert.pem ]; then + echo "Step 1: Login to Cloudflare (browser will open)..." + cloudflared tunnel login +else + echo "✓ Already logged in to Cloudflare" +fi + +# Check if tunnel already exists +if cloudflared tunnel list 2>/dev/null | grep -q "cbf-dev-tunnel"; then + echo "✓ Tunnel 'cbf-dev-tunnel' already exists" +else + echo "" + echo "Step 2: Creating tunnel 'cbf-dev-tunnel'..." + cloudflared tunnel create cbf-dev-tunnel +fi + +# Route DNS +echo "" +echo "Step 3: Setting up DNS route for tunnel.cambeerfestival.app..." +cloudflared tunnel route dns cbf-dev-tunnel tunnel.cambeerfestival.app + +echo "" +echo "✅ Setup complete! You can now run: MISE_ENV=dev ./bin/mise run dev-tunnel" +''' + +[tasks.dev-tunnel] +run = ''' +# Start Cloudflare Tunnel in the background +echo "Starting Cloudflare Tunnel..." +cloudflared tunnel --config .cloudflared/config.yml run & +TUNNEL_PID=$! + +# Wait for tunnel to be ready +echo "Waiting for tunnel to start..." +sleep 3 + +echo "" +echo "✅ Tunnel running at: https://tunnel.cambeerfestival.app" +echo "" +echo "Starting Flutter dev server on http://localhost:8080" +echo "Press Ctrl+C to stop both services." +echo "" + +# Cleanup function +cleanup() { + echo "" + echo "Stopping tunnel..." + kill $TUNNEL_PID 2>/dev/null + exit +} + +# Set up cleanup on exit +trap cleanup EXIT INT TERM + +# Run Flutter in foreground (so you can use 'r' for hot reload, etc.) +flutter run -d web-server --web-port 8080 +''' diff --git a/mise.toml b/mise.toml index 9b7896f5..7989634f 100644 --- a/mise.toml +++ b/mise.toml @@ -18,6 +18,3 @@ echo "To view HTML report, install lcov and run: genhtml coverage/lcov.info -o c [tasks.analyze] run = 'flutter analyze --no-fatal-infos' - -[tasks.dev] -run = 'flutter run -d web-server --web-port 8080'