Skip to content

Commit cb65d8c

Browse files
Fix first-load frontend API routing for ACA private backend
1 parent 965f2d3 commit cb65d8c

3 files changed

Lines changed: 39 additions & 7 deletions

File tree

src/backend/app.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ def create_app() -> FastAPI:
160160
# app.include_router(agents_router, prefix="/api/agents", tags=["agents"])
161161

162162
@app.get("/health")
163+
@app.get("/api/health")
163164
async def health_check():
164165
"""Health check endpoint."""
165166
return {"status": "healthy"}

src/frontend/src/api/config.js

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,41 @@ export let config = {
1212
ENABLE_AUTH: false,
1313
};
1414

15-
export function setApiUrl(url) {
16-
if (url) {
17-
API_URL = `${url}/api`;
15+
function resolveBrowserApiUrl(url) {
16+
if (!url || typeof url !== "string") {
17+
return null;
18+
}
19+
20+
const trimmedUrl = url.trim();
21+
if (!trimmedUrl) {
22+
return null;
1823
}
24+
25+
const normalizedInput = trimmedUrl.replace(/\/+$/, "");
26+
27+
try {
28+
const parsed = new URL(normalizedInput, window.location.origin);
29+
30+
if (parsed.origin !== window.location.origin) {
31+
const backendIsLocal = parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1";
32+
const browserIsLocal = window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1";
33+
34+
// In deployed environments, enforce same-origin API access so requests
35+
// flow through the frontend reverse proxy instead of direct backend calls.
36+
if (!(backendIsLocal && browserIsLocal)) {
37+
return null;
38+
}
39+
}
40+
41+
const normalizedParsed = parsed.toString().replace(/\/+$/, "");
42+
return normalizedParsed.endsWith("/api") ? normalizedParsed : `${normalizedParsed}/api`;
43+
} catch {
44+
return null;
45+
}
46+
}
47+
48+
export function setApiUrl(url) {
49+
API_URL = resolveBrowserApiUrl(url);
1950
}
2051

2152
export function setEnvData(configData) {

src/frontend/src/main.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { FluentProvider, webLightTheme } from '@fluentui/react-components';
66
import { Provider } from 'react-redux';
77
import { store } from './store/store';
88
import AuthProvider from './msal-auth/AuthProvider';
9-
import { setEnvData, setApiUrl, config as defaultConfig } from './api/config';
9+
import { setEnvData, setApiUrl, getApiUrl, config as defaultConfig } from './api/config';
1010
import { initializeMsalInstance } from './msal-auth/msalInstance';
1111

1212
const Main = () => {
@@ -47,10 +47,10 @@ const Main = () => {
4747
async function checkConnection() {
4848
if (!config) return;
4949

50-
const baseURL = config.API_URL.replace(/\/api$/, ''); // Remove '/api' if it appears at the end
51-
console.log('Checking connection to:', baseURL);
50+
const healthUrl = `${getApiUrl()}/health`;
51+
console.log('Checking connection to:', healthUrl);
5252
try {
53-
await fetch(`${baseURL}/health`);
53+
await fetch(healthUrl);
5454
} catch (error) {
5555
console.error('Error connecting to backend:', error);
5656
}

0 commit comments

Comments
 (0)