From 6c105f5b767c4452c492efd75861790e54c5d1b4 Mon Sep 17 00:00:00 2001 From: Aravind Date: Mon, 24 Aug 2026 21:13:12 +0530 Subject: [PATCH] changes --- .env | 41 +++++++++++++++++++++++++++++++++++++++++ .env.example | 17 +++++++++++++++++ .gitignore | 6 ++---- Dockerfile | 19 +++++++++++++++++++ vite.config.js | 2 ++ 5 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..e767daa --- /dev/null +++ b/.env @@ -0,0 +1,41 @@ +# ============================================================================ +# Krow frontend — example environment +# +# Copy to .env and adjust. .env is gitignored. +# +# cp .env.example .env +# +# Vite only exposes variables prefixed with VITE_ to client code, and it reads +# these at build/dev-server start — changing one needs a restart, not a reload. +# ============================================================================ + +# Where the browser sends API requests. +# +# A SAME-ORIGIN PATH, not a host. The browser asks its own origin for +# /api/v1/..., and something on that origin forwards it to the Go API: +# in development the Vite proxy (see `server.proxy` in vite.config.js), in +# production the same web server that serves the built assets (see nginx.conf). +# +# browser → localhost:5173/api/v1 → Vite proxy → 127.0.0.1:8080/api/v1 +# +# THIS MUST STAY A PATH. Pointing it at http://127.0.0.1:8080/api/v1 makes every +# request cross-site, and the session cookie stops working in two separate ways: +# +# 1. The cookie is SameSite=Lax, and a Lax cookie is not sent on a cross-site +# subresource request. A browser treats localhost:5173 and 127.0.0.1:8080 +# as different sites, so the cookie would be set at login and then never +# sent again. +# 2. Because the transport sends `credentials: 'include'`, the browser +# requires `Access-Control-Allow-Credentials: true` on the preflight +# response. The API does not send it — deliberately, because the supported +# arrangement is same-origin — so Chrome discards the preflight and never +# dispatches the real request. The symptom is an OPTIONS that answers 204 +# followed by a POST that never reaches the server at all. +# +# Both failures are silent from the page's point of view, which is why this +# comment is longer than the value. +VITE_API_BASE_URL=/api/v1 + +# Where the Vite dev proxy forwards /api. Only read by vite.config.js, never by +# client code. +VITE_API_PROXY_TARGET=https://mcp.krowforce.com diff --git a/.env.example b/.env.example index e767daa..243c562 100644 --- a/.env.example +++ b/.env.example @@ -36,6 +36,23 @@ # comment is longer than the value. VITE_API_BASE_URL=/api/v1 +# PRODUCTION BUILDS ARE DIFFERENT. The relative value above is correct only +# where something on the page's own origin forwards /api — the Vite proxy in +# development. The deployed frontend at platform.krowforce.com is a static nginx +# host with no such forward (see nginx.conf: no `location /api/`), so a relative +# path makes the login POST land on a static route and answer 405 Method Not +# Allowed. +# +# The production value is therefore absolute, and it is set as a build-time +# environment variable rather than here, because .dockerignore excludes .env* +# and no env file reaches the image build: +# +# ARG VITE_API_BASE_URL=https://mcp.krowforce.com/api/v1 (see Dockerfile) +# +# platform.krowforce.com and mcp.krowforce.com are different origins but the +# same site, so the SameSite=Lax session cookie is still sent — which is why +# production works cross-origin while localhost cannot. + # Where the Vite dev proxy forwards /api. Only read by vite.config.js, never by # client code. VITE_API_PROXY_TARGET=https://mcp.krowforce.com diff --git a/.gitignore b/.gitignore index 29844e2..f2a82a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ #env -.env -.env.* + # ...but the template belongs in the repository: it is the one place the API's # location is documented, and a checkout with no .env needs it. !.env.example @@ -30,6 +29,5 @@ dist-ssr *.sln *.sw? -.env -.vite + base44/.app.jsonc diff --git a/Dockerfile b/Dockerfile index e822330..76e626b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,6 +14,25 @@ COPY package.json package-lock.json ./ RUN npm ci --no-audit --no-fund COPY . . + +# The API origin, baked into the bundle at build time. +# +# Vite inlines VITE_* variables during `npm run build`; there is no runtime +# configuration for a static bundle. It has to be an environment variable here +# because .dockerignore excludes .env*, so no env file ever reaches this stage — +# and without a value the client falls back to a relative /api/v1, which the +# nginx runtime stage below serves as a static path. That answers a login POST +# with 405 Method Not Allowed, because static file serving permits only +# GET/HEAD. +# +# It must include the /api/v1 suffix: httpClient.js builds each URL as +# `${API_BASE_URL}${path}` where path is `/auth/login`. +# +# Override per environment with: +# docker build --build-arg VITE_API_BASE_URL=https://other.example.com/api/v1 . +ARG VITE_API_BASE_URL=https://mcp.krowforce.com/api/v1 +ENV VITE_API_BASE_URL=$VITE_API_BASE_URL + RUN npm run build # ---- Runtime stage ---- diff --git a/vite.config.js b/vite.config.js index 2a157fe..bc6b80e 100644 --- a/vite.config.js +++ b/vite.config.js @@ -60,6 +60,8 @@ export default defineConfig({ }, }, server: { + // Expose server over network (0.0.0.0) + host: true, // Honor a port assigned by the environment; fall back to Vite's default. port: process.env.PORT ? Number(process.env.PORT) : 5173,