From f7e31d9387c163480b9c32bd7c183d87cc67104e Mon Sep 17 00:00:00 2001 From: Izalia Mae Date: Sat, 30 Mar 2024 05:33:26 -0400 Subject: [PATCH] add cors headers to api routes --- relay/frontend/base.haml | 2 +- relay/http_client.py | 12 ++++++++---- relay/views/activitypub.py | 2 +- relay/views/api.py | 16 ++++++++++++++-- relay/views/base.py | 4 ++++ relay/views/frontend.py | 2 +- 6 files changed, 29 insertions(+), 9 deletions(-) diff --git a/relay/frontend/base.haml b/relay/frontend/base.haml index 7b366ab..5c4bc1b 100644 --- a/relay/frontend/base.haml +++ b/relay/frontend/base.haml @@ -14,7 +14,7 @@ %link(rel="stylesheet" type="text/css" href="/theme/{{config.theme}}.css" nonce="{{view.request['hash']}}" class="theme") %link(rel="stylesheet" type="text/css" href="/static/style.css" nonce="{{view.request['hash']}}") %link(rel="manifest" href="/manifest.json") - %script(type="application/javascript" src="/static/api.js" nonce="{{view.request['hash']}}", defer) + %script(type="application/javascript" src="/static/api.js" nonce="{{view.request['hash']}}" defer) -block head %body diff --git a/relay/http_client.py b/relay/http_client.py index ad42331..04533c5 100644 --- a/relay/http_client.py +++ b/relay/http_client.py @@ -137,11 +137,13 @@ class HttpClient: logging.verbose('Failed to parse JSON') return None - except ClientSSLError: + except ClientSSLError as e: logging.verbose('SSL error when connecting to %s', urlparse(url).netloc) + logging.warning(str(e)) - except (AsyncTimeoutError, ClientConnectionError): + except (AsyncTimeoutError, ClientConnectionError) as e: logging.verbose('Failed to connect to %s', urlparse(url).netloc) + logging.warning(str(e)) except Exception: traceback.print_exc() @@ -210,11 +212,13 @@ class HttpClient: logging.debug("headers: %s", json.dumps(headers, indent = 4)) return - except ClientSSLError: + except ClientSSLError as e: logging.warning('SSL error when pushing to %s', urlparse(url).netloc) + logging.warning(str(e)) - except (AsyncTimeoutError, ClientConnectionError): + except (AsyncTimeoutError, ClientConnectionError) as e: logging.warning('Failed to connect to %s for message push', urlparse(url).netloc) + logging.warning(str(e)) # prevent workers from being brought down except Exception: diff --git a/relay/views/activitypub.py b/relay/views/activitypub.py index dc2115f..f2eff48 100644 --- a/relay/views/activitypub.py +++ b/relay/views/activitypub.py @@ -116,7 +116,7 @@ class ActorView(View): return Response.new_error(400, 'actor missing public key', 'json') try: - await self.signer.validate_aiohttp_request(self.request) + await self.signer.validate_request_async(self.request) except aputils.SignatureFailureError as e: logging.verbose('signature validation failed for "%s": %s', self.actor.id, e) diff --git a/relay/views/api.py b/relay/views/api.py index 92e29d8..04b9af8 100644 --- a/relay/views/api.py +++ b/relay/views/api.py @@ -18,6 +18,12 @@ if typing.TYPE_CHECKING: from typing import Any +ALLOWED_HEADERS = { + 'accept', + 'authorization', + 'content-type' +} + PUBLIC_API_PATHS: Sequence[tuple[str, str]] = ( ('GET', '/api/v1/relay'), ('GET', '/api/v1/instance'), @@ -48,14 +54,20 @@ async def handle_api_path(request: Request, handler: Callable) -> Response: request['token'] = None request['user'] = None - if check_api_path(request.method, request.path): + if request.method != "OPTIONS" and check_api_path(request.method, request.path): if not request['token']: return Response.new_error(401, 'Missing token', 'json') if not request['user']: return Response.new_error(401, 'Invalid token', 'json') - return await handler(request) + response = await handler(request) + + if request.path.startswith('/api'): + response.headers['Access-Control-Allow-Origin'] = '*' + response.headers['Access-Control-Allow-Headers'] = ', '.join(ALLOWED_HEADERS) + + return response @register_route('/api/v1/token') diff --git a/relay/views/base.py b/relay/views/base.py index 3d7d718..7cf8311 100644 --- a/relay/views/base.py +++ b/relay/views/base.py @@ -62,6 +62,10 @@ class View(AbstractView): return await handler(self.request, **self.request.match_info, **kwargs) + async def options(self, request: Request) -> Response: + return Response.new() + + @cached_property def allowed_methods(self) -> Sequence[str]: return tuple(self.handlers.keys()) diff --git a/relay/views/frontend.py b/relay/views/frontend.py index 4aed045..2b5bec0 100644 --- a/relay/views/frontend.py +++ b/relay/views/frontend.py @@ -44,7 +44,7 @@ async def handle_frontend_path(request: web.Request, handler: Callable) -> Respo response = await handler(request) - if not request['user'] and request['token']: + if not request.path.startswith('/api') and not request['user'] and request['token']: response.del_cookie('user-token') return response