Created
November 2, 2025 20:04
-
-
Save MonteLogic/2a0a90d4d2b77969cec57e9bc5cbd858 to your computer and use it in GitHub Desktop.
Revisions
-
MonteLogic created this gist
Nov 2, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,129 @@ // scripts/mobile-web-dev.js const { networkInterfaces } = require('os'); const { spawn } = require('child_process'); const net = require('net'); // --- 1. Find the local IP address --- const nets = networkInterfaces(); let localIp = 'localhost'; // Iterate over network interfaces to find the non-internal IPv4 address for (const name of Object.keys(nets)) { for (const netInterface of nets[name]) { // Skip over internal (e.g. 127.0.0.1) and non-IPv4 addresses if (netInterface.family === 'IPv4' && !netInterface.internal) { localIp = netInterface.address; break; } } } // --- 2. Function to check if a port is available --- function isPortAvailable(port) { return new Promise((resolve) => { const server = net.createServer(); server.once('error', (err) => { if (err.code === 'EADDRINUSE') { resolve(false); // Port is in use } else { resolve(false); // Other error, assume port not available } }); server.once('listening', () => { server.once('close', () => { resolve(true); // Port is available }); server.close(); }); server.listen(port); }); } // --- 3. Find an available port starting from 3000 --- async function findAvailablePort(startPort = 3000, maxAttempts = 100) { console.log(`\nπ Looking for an available port starting from ${startPort}...`); for (let port = startPort; port < startPort + maxAttempts; port++) { const available = await isPortAvailable(port); if (available) { console.log(`β Found available port: ${port}\n`); return port; } process.stdout.write(` Port ${port} is in use, trying ${port + 1}...\r`); } throw new Error(`Could not find an available port after ${maxAttempts} attempts`); } // --- 4. Main function to start the server --- async function startServer() { try { const port = await findAvailablePort(3000); // Print the mobile URL console.log(`\nπ Server starting on port ${port}...`); console.log(`π± Access on your phone at: http://${localIp}:${port}\n`); console.log(`π» Or on your computer at: http://localhost:${port}\n`); // Security warning console.log(`\nπ SECURITY WARNING:`); console.log(` This server is accessible to anyone on your local network (${localIp}:${port})`); console.log(` β οΈ Risks:`); console.log(` - Dev server may expose stack traces and debug info`); console.log(` - Public API endpoints: /api/generate-basic-siddur, /blog, /`); console.log(` - Could be exploited for DoS (resource exhaustion)`); console.log(` β Protections:`); console.log(` - Cannot directly hack your machine`); console.log(` - Clerk auth protects most routes`); console.log(` - Only accessible on local network (not internet)`); console.log(` π‘ Recommendations:`); console.log(` - Only use on trusted networks (home/work)`); console.log(` - Stop the server when not in use`); console.log(` - Don't use on public Wi-Fi\n`); console.log(`\nβ οΈ IMPORTANT: For Clerk to work on your phone, add this URL to your Clerk dashboard:`); console.log(` - Go to https://dashboard.clerk.com β Your App β Settings β Domains`); console.log(` - Add: ${localIp}:${port}`); console.log(` - Or add a wildcard pattern for your local network if needed\n`); // Set environment variables for Clerk to recognize the domain const env = { ...process.env, NEXT_PUBLIC_CLERK_FRONTEND_API: process.env.NEXT_PUBLIC_CLERK_FRONTEND_API || '', // Set the domain that Clerk will use for redirects CLERK_DOMAIN: `${localIp}:${port}`, }; // Start the Next.js dev server const child = spawn('npx', ['next', 'dev', '-H', '0.0.0.0', '-p', port.toString()], { // Pipe the server's output (logs, errors, etc.) to this script's console stdio: 'inherit', env: env, }); // Handle errors from the child process child.on('error', (err) => { console.error('Failed to start Next.js server:', err); process.exit(1); }); // Handle process exit child.on('exit', (code) => { if (code !== 0) { console.error(`Next.js server exited with code ${code}`); process.exit(code); } }); } catch (error) { console.error('Error starting server:', error.message); process.exit(1); } } // Start the server startServer();