diff --git a/dev.sh b/dev.sh index 3088327..b91221b 100755 --- a/dev.sh +++ b/dev.sh @@ -21,13 +21,14 @@ if [ "$SSL" = "true" ]; then fi NG_SERVE="cd toju-app && npx ng serve --host=0.0.0.0 --ssl --ssl-cert=../.certs/localhost.crt --ssl-key=../.certs/localhost.key" - WAIT_URL="https://localhost:4200" - HEALTH_URL="https://localhost:3001/api/health" + # Use 127.0.0.1 so wait-on does not hit a stale HTTP listener on localhost (::1). + WAIT_URL="https://127.0.0.1:4200" + HEALTH_URL="https://127.0.0.1:3001/api/health" export NODE_TLS_REJECT_UNAUTHORIZED=0 else NG_SERVE="cd toju-app && npx ng serve --host=0.0.0.0" - WAIT_URL="http://localhost:4200" - HEALTH_URL="http://localhost:3001/api/health" + WAIT_URL="http://127.0.0.1:4200" + HEALTH_URL="http://127.0.0.1:3001/api/health" fi exec npx concurrently --kill-others \ diff --git a/electron/window/create-window.ts b/electron/window/create-window.ts index 7471dcf..1270f2d 100644 --- a/electron/window/create-window.ts +++ b/electron/window/create-window.ts @@ -11,6 +11,7 @@ import * as fs from 'fs'; import * as path from 'path'; import { DESKTOP_APP_DISPLAY_NAME } from '../app/desktop-branding.rules'; import { readDesktopSettings } from '../desktop-settings'; +import { resolveDevelopmentClientUrl } from './dev-client-url.rules'; let mainWindow: BrowserWindow | null = null; let tray: Tray | null = null; @@ -277,11 +278,7 @@ export async function createWindow(): Promise { } if (process.env['NODE_ENV'] === 'development') { - const devUrl = process.env['SSL'] === 'true' - ? 'https://localhost:4200' - : 'http://localhost:4200'; - - await mainWindow.loadURL(devUrl); + await mainWindow.loadURL(resolveDevelopmentClientUrl(process.env['SSL'] === 'true')); if (process.env['DEBUG_DEVTOOLS'] === '1') { mainWindow.webContents.openDevTools(); diff --git a/electron/window/dev-client-url.rules.spec.ts b/electron/window/dev-client-url.rules.spec.ts new file mode 100644 index 0000000..991d180 --- /dev/null +++ b/electron/window/dev-client-url.rules.spec.ts @@ -0,0 +1,26 @@ +import { + describe, + expect, + it +} from 'vitest'; + +import { + DEV_CLIENT_HOST, + DEV_CLIENT_PORT, + resolveDevelopmentClientUrl +} from './dev-client-url.rules'; + +describe('dev-client-url.rules', () => { + it('targets loopback IPv4 so dev wait-on avoids stale localhost IPv6 listeners', () => { + expect(DEV_CLIENT_HOST).toBe('127.0.0.1'); + expect(DEV_CLIENT_PORT).toBe(4200); + }); + + it('builds the HTTP dev client URL', () => { + expect(resolveDevelopmentClientUrl(false)).toBe('http://127.0.0.1:4200'); + }); + + it('builds the HTTPS dev client URL', () => { + expect(resolveDevelopmentClientUrl(true)).toBe('https://127.0.0.1:4200'); + }); +}); diff --git a/electron/window/dev-client-url.rules.ts b/electron/window/dev-client-url.rules.ts new file mode 100644 index 0000000..fe8621e --- /dev/null +++ b/electron/window/dev-client-url.rules.ts @@ -0,0 +1,8 @@ +export const DEV_CLIENT_HOST = '127.0.0.1'; +export const DEV_CLIENT_PORT = 4200; + +export function resolveDevelopmentClientUrl(sslEnabled: boolean): string { + const scheme = sslEnabled ? 'https' : 'http'; + + return `${scheme}://${DEV_CLIENT_HOST}:${DEV_CLIENT_PORT}`; +} diff --git a/package.json b/package.json index ac2a396..417872b 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "server:start": "cd server && npm start", "server:dev": "cd server && npm run dev", "electron": "npm run build && npm run build:electron && node tools/launch-electron.js . --no-sandbox --disable-dev-shm-usage", - "electron:dev": "concurrently \"npm run start\" \"wait-on http://localhost:4200 && npm run build:electron && cross-env NODE_ENV=development node tools/launch-electron.js . --no-sandbox --disable-dev-shm-usage\"", + "electron:dev": "concurrently \"npm run start\" \"wait-on http://127.0.0.1:4200 && npm run build:electron && cross-env NODE_ENV=development node tools/launch-electron.js . --no-sandbox --disable-dev-shm-usage\"", "electron:full": "./dev.sh", "electron:full:build": "npm run build:all && concurrently --kill-others \"cd server && npm start\" \"cross-env NODE_ENV=production node tools/launch-electron.js . --no-sandbox --disable-dev-shm-usage\"", "migration:generate": "typeorm migration:generate electron/migrations/Auto -d dist/electron/data-source.js",