LibreChat icon indicating copy to clipboard operation
LibreChat copied to clipboard

fix: add basePath pattern to support login/register and image paths

Open catmeme opened this issue 6 months ago • 1 comments

Summary

This PR is meant to address https://github.com/danny-avila/LibreChat/issues/10013 which is a bug in the new feature, https://github.com/danny-avila/LibreChat/pull/9155

I've included unit tests, and run the test suites in this project. A simplified test case is included below.

This is currently relying on DOMAIN_CLIENT, wasn't sure if it you would like to add a dedicated environment variable, or how you'd like to approach this fix in general, but I gave it my best shot.

  • Server-side path injection - Created getBasePath() utility that reads DOMAIN_CLIENT env var and prepends subdirectory paths (e.g., /librechat) to all image URLs in AI-generated responses, tool outputs (StableDiffusion), and code interpreter results

  • Client-side path resolution - Updated React components (Image.tsx, markdown renderers) to prepend the base URL from the HTML <base> tag to image paths, fixing broken images when the app is served from a subdirectory like https://example.com/librechat/

  • Security & routing updates - Fixed image validation middleware to correctly validate paths with base prefixes, updated auth redirects to use base-aware URLs (loginPage(), registerPage()), and added comprehensive test coverage (150+ new tests) for subdirectory deployment scenarios

Change Type

  • [x] Bug fix (non-breaking change which fixes an issue)

Testing

With the following files in the project root:

  1. Ensure you have a configured local dev environment following this project's README.md, as well as having OpenAI image generation configured
  2. docker compose up --build
  3. Navigate to http://localhost/librechat and login
  4. Generate an image, it should display properly instead of not displaying at all.

Test Configuration:

docker-compose.override.yml

services:
  # Build and use our complete fixes image
  api:
    build:
      context: .
      dockerfile: Dockerfile.multi
      target: api-build
    image: librechat-fixed:latest
    env_file:
      - .env
    environment:
      - IMAGE_GEN_OAI_API_KEY=<key-here-or-env>
    volumes:
      # Mount directories for file storage
      - ./data/logs:/app/api/logs
      - ./data/uploads:/app/uploads
      - ./data/images:/app/client/public/images
      - ./librechat.yaml:/app/librechat.yaml

  # Add Nginx reverse proxy to test the subdirectory scenario
  nginx:
    image: nginx:alpine
    container_name: LibreChat-Nginx
    ports:
      - "80:80"
    depends_on:
      - api
    volumes:
      - ./nginx-test.conf:/etc/nginx/conf.d/default.conf
    restart: unless-stopped

nginx-test.conf

# Nginx configuration for LibreChat subdirectory deployment
# LibreChat now handles subdirectory-aware image paths internally

server {
    listen 80;
    server_name localhost;

    # Serve LibreChat from the /librechat/ path
    # LibreChat's built-in subdirectory support handles all routing including images
    location /librechat/ {
        proxy_pass http://api:3080/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        
        # Additional headers for better proxy handling
        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;
        
        # Critical settings for SSE/streaming support
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 300s;
        proxy_connect_timeout 75s;
        proxy_send_timeout 300s;
        
        # Ensure chunked encoding works properly for streaming
        chunked_transfer_encoding on;
    }

    # Root redirect to librechat
    location = / {
        return 301 /librechat/;
    }

    # Health check endpoint
    location /health {
        proxy_pass http://api:3080/health;
    }
}

Checklist

  • [x] My code adheres to this project's style guidelines
  • [x] I have performed a self-review of my own code
  • [x] I have commented in any complex areas of my code
  • [x] My changes do not introduce new warnings
  • [x] I have written tests demonstrating that my changes are effective or that my feature works
  • [x] Local unit tests pass with my changes

catmeme avatar Oct 14 '25 14:10 catmeme

@danny-avila any feedback on this?

catmeme avatar Oct 20 '25 13:10 catmeme