This is an automated email from the ASF dual-hosted git repository.
jbonofre pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris-tools.git
The following commit(s) were added to refs/heads/main by this push:
new 6400f26 feat(fix): switch console to direct server API calls with
CORS (#147)
6400f26 is described below
commit 6400f2678d3a09945f428986d6fb12159e4326ba
Author: Artur Rakhmatulin <[email protected]>
AuthorDate: Sun Feb 1 08:46:06 2026 +0100
feat(fix): switch console to direct server API calls with CORS (#147)
* feat: switch console to direct server API calls with CORS
- Removed Vite dev server proxy configuration
- Removed nginx proxy from Docker setup
- Updated API client to use absolute URLs
- Updated README with Quarkus CORS configuration options
* feat: add VITE_OAUTH_TOKEN_URL
* fix: fix comments
* fix: rename variables to GENERIC_TABLES_BASE_URL
* fix: fix readme
* fix: fix readme
---
console/README.md | 69 +++++++++++++++++++++++++++++++++-
console/docker/generate-config.sh | 6 +--
console/docker/nginx.conf | 37 ------------------
console/helm/templates/deployment.yaml | 2 +-
console/src/api/auth.ts | 7 +---
console/src/api/client.ts | 10 ++---
console/vite.config.ts | 45 ----------------------
7 files changed, 77 insertions(+), 99 deletions(-)
diff --git a/console/README.md b/console/README.md
index 8467fef..cb904be 100644
--- a/console/README.md
+++ b/console/README.md
@@ -45,12 +45,77 @@ Create a `.env` file based on `.env.example`:
```env
VITE_POLARIS_API_URL=http://localhost:8181
-VITE_POLARIS_REALM=POLARIS
+VITE_POLARIS_REALM=POLARIS
VITE_POLARIS_PRINCIPAL_SCOPE=PRINCIPAL_ROLE:ALL
VITE_POLARIS_REALM_HEADER_NAME=Polaris-Realm # optional, defaults to
"Polaris-Realm"
-VITE_OAUTH_TOKEN_URL=http://localhost:8181/api/v1/oauth/tokens # optional
+VITE_OAUTH_TOKEN_URL=http://localhost:8181/api/catalog/v1/oauth/tokens #
optional, defaults to ${VITE_POLARIS_API_URL}/api/catalog/v1/oauth/tokens
```
+> **Note:** The console makes direct API calls to the Polaris server. Ensure
CORS is properly configured on the server (see below).
+
+### Server-Side CORS Configuration
+
+The console makes direct API calls to the Polaris server. Configure CORS on
your Polaris server (Quarkus-based).
+
+#### Option 1: Using application.properties
+
+Add to your Polaris `application.properties` file:
+
+```properties
+quarkus.http.cors.enabled=true
+quarkus.http.cors.origins=https://console.polaris.service
+quarkus.http.cors.methods=GET,POST,PUT,DELETE,PATCH,OPTIONS
+quarkus.http.cors.headers=Content-Type,Authorization,Polaris-Realm
+quarkus.http.cors.exposed-headers=*
+quarkus.http.cors.access-control-allow-credentials=true
+quarkus.http.cors.access-control-max-age=PT10M
+```
+
+#### Option 2: Using Environment Variables
+
+Set these environment variables:
+
+```bash
+QUARKUS_HTTP_CORS_ENABLED=true
+QUARKUS_HTTP_CORS_ORIGINS=https://console.polaris.service
+QUARKUS_HTTP_CORS_METHODS=GET,POST,PUT,DELETE,PATCH,OPTIONS
+QUARKUS_HTTP_CORS_HEADERS=Content-Type,Authorization,Polaris-Realm,X-Request-ID
+QUARKUS_HTTP_CORS_EXPOSED_HEADERS=*
+QUARKUS_HTTP_CORS_ACCESS_CONTROL_ALLOW_CREDENTIALS=true
+QUARKUS_HTTP_CORS_ACCESS_CONTROL_MAX_AGE=PT10M
+```
+
+#### Option 3: Using Kubernetes ConfigMap
+
+For Kubernetes/Helm deployments you need configure `cors` section in
[values.yaml](https://polaris.apache.org/releases/1.3.0/helm/):
+
+```yaml
+cors:
+ allowedOrigins:
+ - "https://console.polaris.service"
+ allowedMethods:
+ - "GET"
+ - "POST"
+ - "PUT"
+ - "DELETE"
+ - "PATCH"
+ - "OPTIONS"
+ allowedHeaders:
+ - "Content-Type"
+ - "Authorization"
+ - "Polaris-Realm"
+ - "X-Request-ID"
+ exposedHeaders:
+ - "*"
+ accessControlMaxAge: "PT10M"
+ accessControlAllowCredentials: true
+
+advancedConfig:
+ quarkus.http.cors.enabled: "true"
+```
+
+See [Quarkus CORS documentation](https://quarkus.io/guides/security-cors) for
more details.
+
## Project Structure
```
diff --git a/console/docker/generate-config.sh
b/console/docker/generate-config.sh
index f08663f..f5b182f 100644
--- a/console/docker/generate-config.sh
+++ b/console/docker/generate-config.sh
@@ -16,10 +16,10 @@
# specific language governing permissions and limitations
# under the License.
-# Generate nginx configuration with the backend URL
-envsubst '${VITE_POLARIS_API_URL}' <
/opt/app-root/etc/nginx.d/default.conf.template >
/opt/app-root/etc/nginx.d/default.conf
+# Copy nginx configuration (no substitution needed since we use direct API
calls)
+cp /opt/app-root/etc/nginx.d/default.conf.template
/opt/app-root/etc/nginx.d/default.conf
-echo "Generated nginx config with backend: ${VITE_POLARIS_API_URL}"
+echo "Configured nginx for static file serving"
# Generate runtime configuration from environment variables
cat > /opt/app-root/src/config.js << EOF
diff --git a/console/docker/nginx.conf b/console/docker/nginx.conf
index dffe1c7..80ea80e 100644
--- a/console/docker/nginx.conf
+++ b/console/docker/nginx.conf
@@ -32,43 +32,6 @@ server {
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
- # Proxy API requests to Polaris backend
- # Backend URL is injected at container startup via envsubst
- location /api/ {
- proxy_pass ${VITE_POLARIS_API_URL};
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
-
- # Disable buffering for streaming responses
- proxy_buffering off;
-
- # Timeouts
- proxy_connect_timeout 60s;
- proxy_send_timeout 60s;
- proxy_read_timeout 60s;
- }
-
- # Proxy Polaris-specific API requests to Polaris backend
- # Rewrite /polaris/v1/* to /api/catalog/polaris/v1/*
- location /polaris/ {
- rewrite ^/polaris/(.*)$ /api/catalog/polaris/$1 break;
- proxy_pass ${VITE_POLARIS_API_URL};
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
-
- # Disable buffering for streaming responses
- proxy_buffering off;
-
- # Timeouts
- proxy_connect_timeout 60s;
- proxy_send_timeout 60s;
- proxy_read_timeout 60s;
- }
-
# Serve static files
location / {
try_files $uri $uri/ /index.html;
diff --git a/console/helm/templates/deployment.yaml
b/console/helm/templates/deployment.yaml
index 3a8176d..138b560 100644
--- a/console/helm/templates/deployment.yaml
+++ b/console/helm/templates/deployment.yaml
@@ -49,7 +49,7 @@ spec:
- name: VITE_POLARIS_REALM
value: {{ .Values.env.polarisRealm | quote }}
- name: VITE_POLARIS_PRINCIPAL_SCOPE
- value: { { .Values.env.polarisPrincipalScope | quote } }
+ value: {{ .Values.env.polarisPrincipalScope | quote }}
- name: VITE_OAUTH_TOKEN_URL
value: {{ .Values.env.oauthTokenUrl | quote }}
readinessProbe:
diff --git a/console/src/api/auth.ts b/console/src/api/auth.ts
index dd20584..11bd42d 100644
--- a/console/src/api/auth.ts
+++ b/console/src/api/auth.ts
@@ -21,14 +21,11 @@ import axios from "axios"
import { apiClient } from "./client"
import { navigate } from "@/lib/navigation"
import { REALM_HEADER_NAME } from "@/lib/constants"
+import { config } from "@/lib/config"
import type { OAuthTokenResponse } from "@/types/api"
-// Always use relative URL to go through the proxy (dev server or production
server)
-// This avoids CORS issues by proxying requests through the server
-// The server.ts proxy handles /api routes in production, and Vite handles
them in development
-const TOKEN_URL = "/api/catalog/v1/oauth/tokens"
+const TOKEN_URL = config.OAUTH_TOKEN_URL ||
`${config.POLARIS_API_URL}/api/catalog/v1/oauth/tokens`
-// Log OAuth URL in development only
if (import.meta.env.DEV) {
console.log("🔐 Using OAuth token URL:", TOKEN_URL)
}
diff --git a/console/src/api/client.ts b/console/src/api/client.ts
index 15e21b8..f82d811 100644
--- a/console/src/api/client.ts
+++ b/console/src/api/client.ts
@@ -20,14 +20,12 @@
import axios, { type AxiosInstance, type InternalAxiosRequestConfig } from
"axios"
import { navigate } from "@/lib/navigation"
import { REALM_HEADER_NAME } from "@/lib/constants"
+import { config } from "@/lib/config"
-// Always use relative URLs to go through the proxy (dev server or production
server)
-// This avoids CORS issues by proxying requests through the server
-// The server.ts proxy handles /api routes in production, and Vite handles
them in development
-const API_BASE_URL = ""
+const API_BASE_URL = config.POLARIS_API_URL
const MANAGEMENT_BASE_URL = `${API_BASE_URL}/api/management/v1`
const CATALOG_BASE_URL = `${API_BASE_URL}/api/catalog/v1`
-const POLARIS_BASE_URL = `${API_BASE_URL}/polaris/v1`
+const GENERIC_TABLES_BASE_URL = `${API_BASE_URL}/api/catalog/polaris/v1`
class ApiClient {
private managementClient: AxiosInstance
@@ -52,7 +50,7 @@ class ApiClient {
})
this.polarisClient = axios.create({
- baseURL: POLARIS_BASE_URL,
+ baseURL: GENERIC_TABLES_BASE_URL,
headers: {
"Content-Type": "application/json",
},
diff --git a/console/vite.config.ts b/console/vite.config.ts
index 63631ce..d9782d2 100644
--- a/console/vite.config.ts
+++ b/console/vite.config.ts
@@ -29,49 +29,4 @@ export default defineConfig({
"@": path.resolve(__dirname, "./src"),
},
},
- server: {
- proxy: {
- "/api": {
- target: process.env.VITE_POLARIS_API_URL || "http://localhost:8181",
- changeOrigin: true,
- secure: false,
- configure: (proxy) => {
- // Only log in development mode
- if (process.env.NODE_ENV === "development") {
- proxy.on("error", (err) => {
- console.error("Proxy error:", err)
- })
- proxy.on("proxyReq", (proxyReq, req) => {
- const target = process.env.VITE_POLARIS_API_URL ||
"http://localhost:8181"
- console.log("📤 Proxying:", req.method, req.url, "→", target +
proxyReq.path)
- })
- proxy.on("proxyRes", (proxyRes, req) => {
- console.log("Received Response from the Target:",
proxyRes.statusCode, req.url)
- })
- }
- },
- },
- "/polaris": {
- target: process.env.VITE_POLARIS_API_URL || "http://localhost:8181",
- changeOrigin: true,
- secure: false,
- rewrite: (path) => path.replace(/^\/polaris/, "/api/catalog/polaris"),
- configure: (proxy) => {
- // Only log in development mode
- if (process.env.NODE_ENV === "development") {
- proxy.on("error", (err) => {
- console.error("Proxy error:", err)
- })
- proxy.on("proxyReq", (proxyReq, req) => {
- const target = process.env.VITE_POLARIS_API_URL ||
"http://localhost:8181"
- console.log("📤 Proxying:", req.method, req.url, "→", target +
proxyReq.path)
- })
- proxy.on("proxyRes", (proxyRes, req) => {
- console.log("Received Response from the Target:",
proxyRes.statusCode, req.url)
- })
- }
- },
- },
- },
- },
})