diff --git a/src/langbot/pkg/api/http/controller/groups/user.py b/src/langbot/pkg/api/http/controller/groups/user.py index 932de0823..6b42d4ea3 100644 --- a/src/langbot/pkg/api/http/controller/groups/user.py +++ b/src/langbot/pkg/api/http/controller/groups/user.py @@ -14,11 +14,6 @@ from ...service.user import ControlPlaneDirectoryRequiredError, PublicRegistrati @group.group_class('user', '/api/v1/user') class UserRouterGroup(group.RouterGroup): - @staticmethod - def _is_loopback_host(hostname: str) -> bool: - normalized = hostname.casefold().rstrip('.') - return normalized in {'localhost', '127.0.0.1', '::1'} - def _validate_space_redirect_uri(self, redirect_uri: str, *, bind: bool) -> str: parsed = urlsplit(redirect_uri) if ( @@ -38,10 +33,6 @@ class UserRouterGroup(group.RouterGroup): elif query: raise ValueError('Invalid LangBot Account login redirect_uri') - # OSS instances can live behind arbitrary domains and gateway ports. - # Accept any HTTPS callback, plus HTTP only for local development. - if parsed.scheme == 'http' and not self._is_loopback_host(parsed.hostname): - raise ValueError('Insecure redirect_uri origin') return redirect_uri async def initialize(self) -> None: diff --git a/tests/integration/api/test_user_space_oauth.py b/tests/integration/api/test_user_space_oauth.py index 42ae4b066..9d22e5b3c 100644 --- a/tests/integration/api/test_user_space_oauth.py +++ b/tests/integration/api/test_user_space_oauth.py @@ -165,7 +165,7 @@ async def test_bind_state_is_account_bound_and_requires_authentication(space_oau @pytest.mark.asyncio -async def test_redirect_allows_dynamic_https_origin_and_loopback_http(space_oauth_api): +async def test_redirect_allows_any_http_or_https_origin(space_oauth_api): _, client = space_oauth_api responses = [ @@ -181,6 +181,8 @@ async def test_redirect_allows_dynamic_https_origin_and_loopback_http(space_oaut 'http://localhost:5300/auth/space/callback', 'http://127.0.0.1:5300/auth/space/callback', 'http://[::1]:5300/auth/space/callback', + 'http://langbot.example/auth/space/callback', + 'http://192.0.2.10:5300/auth/space/callback', ) ] @@ -190,7 +192,7 @@ async def test_redirect_allows_dynamic_https_origin_and_loopback_http(space_oaut @pytest.mark.asyncio -async def test_redirect_rejects_insecure_remote_origin_and_invalid_callback_shape(space_oauth_api): +async def test_redirect_rejects_invalid_callback_shape(space_oauth_api): _, client = space_oauth_api responses = [ @@ -199,7 +201,6 @@ async def test_redirect_rejects_insecure_remote_origin_and_invalid_callback_shap query_string={'redirect_uri': redirect_uri}, ) for redirect_uri in ( - 'http://langbot.example/auth/space/callback', 'https://langbot.example/arbitrary', 'https://langbot.example/auth/space/callback?next=https://evil.example', 'https://user@langbot.example/auth/space/callback',