Serving over HTTP (not https) broken in docker container
Bug description
This was a really tricky one to track down. The crux of the bug is that in the most vanilla, default install of chat-ui using a Docker container, accessing chat-ui over HTTP only is broken out of the box. What I mean by broken is that any rendered content that relies on page.url.origin will have it's connection protocol rendered as HTTPS instead of HTTP. This results in broken images, such as fave-icons, apple touch icons, omni-welcome images, and logos. More critically, however, is that oAuth callback_uri's are also incorrect, causing logins to fail due to invalidate callback uri's in the upstream OIDC provider.
The reason for the unintentional protocol render is the node-adpater for Svelt. The issue is documented here, here., and ultimately indirectly fixed here..
Also: Running the app from source code with the Vite dev build to try to reproduce the issue doesn't work because in dev move the node-adapter doesn't assume/force HTTPS. It must be tested on the "production" build. That was a fun one to realize.
Steps to fix
Add an environment variable simply called "ORIGIN" to match the exact hostname. This will inform the node-adapter of what protocol to render as, and not assume HTTPS for all non-development builds of the app.
Steps to reproduce
Deploy a fresh Docker container for chat-ui, configure it with:
OPENAI_BASE_URL=https://********
OPENAI_API_KEY=********
OPENID_CONFIG={PROVIDER_URL: "****",CLIENT_ID: "chatui",CLIENT_SECRET: "****",SCOPES: "openid profile email"}
COOKIE_SECURE=false
#PUBLIC_ORIGIN=http://mylocaldocker.internal:5173/ # Note: This doesn't appear to work as expected.Access the site over insecure http, observe the broken functionality, icons, and inability to oAuth. To fix, add:
ORIGIN=http://mylocaldocker.internal:5173/Screenshots
After setting ORIGIN:
Notes
For some reason, PUBLIC_ORIGIN has a detrimental effect, causing 404's for rendered assets, but crucially, has zero effect on the incorrect change of the protocol. Assets and oAuth callback uri's are sill assuming HTTPS.
Also not explored: I did not check to see if PUBLIC_ORIGIN is supposed to also translate to the ORIGIN header, and this is the real underlying issue.
Now for the obligatory acknowledgements: Of course, don't do this for production workloads. My use-case is an isolated testing lab with internal certificate authority, OIDC provider, and web host purely for testing and anlaysis. Of course, nobody should ever oAuth over insecure HTTP. However, if the chat-ui documentation suggests it supports an http-only scenario (by use of insecure cookies and PUBLIC_ORIGIN, one would assume the intent is that it work over HTTP after being configured a such.
And lastly, this is probably not an issue for 90% of users who properly deploy an https reverse-proxy in front of this container, which of course I do for for my real/production instance.
Recommendation:
Here's a few possible avenues to fix:
- A simple documentation change to the .env example file to include ORIGIN.
- A code change that PUBLIC_ORIGIN also sets ORIGIN internally.
- Update auth.ts#L533 and change
url.origintoconfig.PUBLIC_ORIGIN
Source: huggingface/chat-ui