Skip to content

Commit ee9de4f

Browse files
StuMasonclaude
andcommitted
fix: Extract host/scheme from request headers for OAuth redirect_uri
Use x-forwarded-proto and x-forwarded-host headers set by reverse proxy instead of relying on query parameters that weren't being populated. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 2733660 commit ee9de4f

File tree

1 file changed

+10
-11
lines changed

1 file changed

+10
-11
lines changed

src/polar_flow_server/api/keys.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from typing import Any
1515
from urllib.parse import urlencode
1616

17-
from litestar import Router, get, post
17+
from litestar import Router, get, post, Request
1818
from litestar.exceptions import NotAuthorizedException, NotFoundException
1919
from litestar.params import Parameter
2020
from litestar.response import Redirect
@@ -105,11 +105,10 @@ def _get_base_url_from_headers(headers: dict[str, str]) -> str:
105105

106106
@get("/oauth/start", status_code=HTTP_303_SEE_OTHER)
107107
async def oauth_start_saas(
108+
request: Request,
108109
session: AsyncSession,
109110
callback_url: str,
110111
client_id: str | None = None,
111-
request_host: str | None = None,
112-
request_scheme: str | None = None,
113112
) -> Redirect:
114113
"""Start OAuth flow for SaaS clients.
115114
@@ -143,10 +142,10 @@ async def oauth_start_saas(
143142
for s in expired:
144143
del _saas_oauth_states[s]
145144

146-
# Build authorization URL
147-
# Note: We use a special SaaS callback endpoint
148-
scheme = request_scheme or "https"
149-
host = request_host or "localhost:8000"
145+
# Build authorization URL - extract host/scheme from request headers
146+
# Coolify/nginx sets x-forwarded-* headers
147+
scheme = request.headers.get("x-forwarded-proto", "https")
148+
host = request.headers.get("x-forwarded-host") or request.headers.get("host", "localhost:8000")
150149
base_url = f"{scheme}://{host}"
151150
redirect_uri = f"{base_url}/oauth/callback"
152151

@@ -165,12 +164,11 @@ async def oauth_start_saas(
165164

166165
@get("/oauth/callback", status_code=HTTP_303_SEE_OTHER)
167166
async def oauth_callback_saas(
167+
request: Request,
168168
session: AsyncSession,
169169
code: str | None = None,
170170
oauth_state: str | None = Parameter(default=None, query="state"),
171171
error: str | None = None,
172-
request_host: str | None = None,
173-
request_scheme: str | None = None,
174172
) -> Redirect:
175173
"""Handle OAuth callback for SaaS clients.
176174
@@ -223,8 +221,9 @@ async def oauth_callback_saas(
223221

224222
# Exchange code for access token
225223
client_secret = token_encryption.decrypt(app_settings.polar_client_secret_encrypted)
226-
scheme = request_scheme or "https"
227-
host = request_host or "localhost:8000"
224+
# Extract host/scheme from request headers (Coolify/nginx sets x-forwarded-*)
225+
scheme = request.headers.get("x-forwarded-proto", "https")
226+
host = request.headers.get("x-forwarded-host") or request.headers.get("host", "localhost:8000")
228227
base_url = f"{scheme}://{host}"
229228
redirect_uri = f"{base_url}/oauth/callback"
230229

0 commit comments

Comments
 (0)