From 44ca64e12037da4cb979eaea54cba49b39c554fc Mon Sep 17 00:00:00 2001 From: latte Date: Fri, 16 Jan 2026 10:43:16 +0000 Subject: [PATCH] fix: Configure HTTPS domain and OAuth callback route - Update configuration for production HTTPS domain (devden.hiddenden.cafe) - Add nginx reverse proxy for /api and /auth routes to backend - Create auth-callback.html to handle Microsoft Entra ID OAuth redirect - Fix API_URL in script.js to use same origin (remove :8000 port) - Add cache-busting query parameter (?v=2) to script.js - Update .env.example with HTTPS requirements documentation This resolves Azure Entra ID redirect URI mismatch and enables proper OAuth authentication flow through the nginx frontend proxy. Co-Authored-By: Claude Sonnet 4.5 --- .env.example | 6 +++++- Dockerfile | 1 + auth-callback.html | 47 ++++++++++++++++++++++++++++++++++++++++++++++ default.conf | 32 +++++++++++++++++++++++++++++++ docker-compose.yml | 4 ++-- index.html | 2 +- script.js | 3 ++- 7 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 auth-callback.html diff --git a/.env.example b/.env.example index 5484389..9811638 100644 --- a/.env.example +++ b/.env.example @@ -13,11 +13,15 @@ OPENAI_MODEL=gpt-4o-mini # API Configuration MAX_TOKENS=4000 TEMPERATURE=0.7 +# For local development use: http://localhost:3000 +# For production use your domain with HTTPS: https://your-domain.com FRONTEND_URL=http://localhost:3000 # Microsoft Entra ID (Azure AD) # Create an app registration at: https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps -# Add redirect URI: http://localhost:3000/auth/callback +# IMPORTANT: Azure requires HTTPS for non-localhost redirect URIs +# For localhost: http://localhost:3000/auth/callback +# For production: https://your-domain.com/auth/callback ENTRA_TENANT_ID=your-tenant-id ENTRA_CLIENT_ID=your-client-id ENTRA_CLIENT_SECRET=your-client-secret diff --git a/Dockerfile b/Dockerfile index 2f1e541..07d82e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,7 @@ COPY default.conf /etc/nginx/conf.d/default.conf # Copy static files to nginx html directory COPY index.html /usr/share/nginx/html/ +COPY auth-callback.html /usr/share/nginx/html/ COPY style.css /usr/share/nginx/html/ COPY script.js /usr/share/nginx/html/ diff --git a/auth-callback.html b/auth-callback.html new file mode 100644 index 0000000..fe887c1 --- /dev/null +++ b/auth-callback.html @@ -0,0 +1,47 @@ + + + + + + DevDen - Authentication + + + +
+
+

Completing authentication...

+
+ + + diff --git a/default.conf b/default.conf index e2dff01..78f2c5b 100644 --- a/default.conf +++ b/default.conf @@ -4,6 +4,38 @@ server { root /usr/share/nginx/html; index index.html; + # Proxy API requests to backend + location /api/ { + proxy_pass http://backend:8000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + 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; + proxy_cache_bypass $http_upgrade; + + # Support for SSE (Server-Sent Events) + proxy_buffering off; + proxy_cache off; + } + + # OAuth callback endpoint - redirect to root with query params + location = /auth/callback { + try_files /auth-callback.html =404; + } + + # Proxy other auth requests to backend + location /auth/ { + proxy_pass http://backend:8000; + proxy_http_version 1.1; + 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; + } + # Enable SPA routing - try to serve the file, then directory, then fallback to index.html location / { try_files $uri $uri/ /index.html; diff --git a/docker-compose.yml b/docker-compose.yml index 4bd8642..3519eda 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,11 +25,11 @@ services: - DEFAULT_PROVIDER=${DEFAULT_PROVIDER:-claude} - CLAUDE_MODEL=${CLAUDE_MODEL:-claude-3-5-sonnet-20241022} - OPENAI_MODEL=${OPENAI_MODEL:-gpt-4-turbo-preview} - - FRONTEND_URL=http://localhost:3000 + - FRONTEND_URL=https://devden.hiddenden.cafe - ENTRA_TENANT_ID=${ENTRA_TENANT_ID} - ENTRA_CLIENT_ID=${ENTRA_CLIENT_ID} - ENTRA_CLIENT_SECRET=${ENTRA_CLIENT_SECRET} - - ENTRA_REDIRECT_URI=${ENTRA_REDIRECT_URI:-http://localhost:3000/auth/callback} + - ENTRA_REDIRECT_URI=https://devden.hiddenden.cafe/auth/callback - JWT_SECRET=${JWT_SECRET:-change-this-in-production} - JWT_EXPIRY_HOURS=${JWT_EXPIRY_HOURS:-24} env_file: diff --git a/index.html b/index.html index 276859b..bafcf08 100644 --- a/index.html +++ b/index.html @@ -63,6 +63,6 @@
- + diff --git a/script.js b/script.js index 55bdb9c..78d85b0 100644 --- a/script.js +++ b/script.js @@ -72,7 +72,8 @@ const welcomeInput = document.getElementById("welcomeInput"); const chatInput = document.getElementById("chatInput"); const loginBtn = document.getElementById("loginBtn"); -const API_URL = "http://localhost:8000"; +// API URL is same as frontend (nginx proxies /api and /auth to backend) +const API_URL = window.location.origin; let isInChat = false;