Skip to content

Commit a98e318

Browse files
🐛 fix(web-server): use X-Forwarded-Proto header for confirmation link scheme 🚑 (#9026)
1 parent e07831a commit a98e318

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

services/web/server/src/simcore_service_webserver/login/_confirmation_web.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from urllib.parse import quote
33

44
from aiohttp import web
5+
from servicelib.common_headers import X_FORWARDED_PROTO
56
from yarl import URL
67

78
from simcore_service_webserver.login._application_keys import (
@@ -26,7 +27,10 @@ def _url_for_confirmation(app: web.Application, code: str) -> URL:
2627
def make_confirmation_link(request: web.Request, code: str) -> str:
2728
assert code # nosec
2829
link = _url_for_confirmation(request.app, code=code)
29-
return f"{request.scheme}://{request.host}{link}"
30+
# Custom header by traefik. See labels in docker-compose as:
31+
# - traefik.http.middlewares.${SWARM_STACK_NAME_NO_HYPHEN}_sslheader.headers.customrequestheaders.X-Forwarded-Proto=http # noqa: E501
32+
scheme = request.headers.get(X_FORWARDED_PROTO, request.scheme)
33+
return f"{scheme}://{request.host}{link}"
3034

3135

3236
@ensure_single_setup(__name__, logger=_logger)

services/web/server/tests/unit/with_dbs/03/login/test_login_confirmation_service.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ async def mock_handler(request: web.Request):
5454
assert confirmation_link.startswith("https://example.com/auth/confirmation/")
5555
assert confirmation.code in confirmation_link
5656

57+
# Step 5: Verify X-Forwarded-Proto header is respected
58+
request_behind_proxy = make_mocked_request(
59+
"GET",
60+
"http://example.com/auth/confirmation/{code}",
61+
app=app,
62+
headers={"Host": "example.com", "X-Forwarded-Proto": "https"},
63+
)
64+
confirmation_link_via_proxy = _confirmation_web.make_confirmation_link(request_behind_proxy, confirmation.code)
65+
assert confirmation_link_via_proxy.startswith("https://example.com/auth/confirmation/")
66+
5767

5868
async def test_expired_confirmation_token(
5969
confirmation_service: ConfirmationService,

0 commit comments

Comments
 (0)