diff --git a/changelog.d/288.bugfix b/changelog.d/288.bugfix new file mode 100644 index 00000000..80470ece --- /dev/null +++ b/changelog.d/288.bugfix @@ -0,0 +1 @@ +Fix a bug introduced in Sygnal 0.9.1 where web pushkeys with missing endpoints would cause an error. diff --git a/docs/applications.md b/docs/applications.md index f04628a5..b102d840 100644 --- a/docs/applications.md +++ b/docs/applications.md @@ -247,7 +247,7 @@ In your web application, [the push manager subscribe method](https://developer.m will return [a subscription](https://developer.mozilla.org/en-US/docs/Web/API/PushSubscription) with an `endpoint` and `keys` property, the latter containing a `p256dh` and `auth` -property. The `p256dh` key is used as the push key, and the push data is expected +property. The `p256dh` key is used as the push key, and the push data must contain `endpoint` and `auth`. You can also set `default_payload` in the push data; any properties set in it will be present in the push messages you receive, so it can be used to pass identifiers specific to your client diff --git a/sygnal/webpushpushkin.py b/sygnal/webpushpushkin.py index fea3c494..da42629d 100644 --- a/sygnal/webpushpushkin.py +++ b/sygnal/webpushpushkin.py @@ -114,7 +114,7 @@ def __init__(self, name: str, sygnal: "Sygnal", config: Dict[str, Any]): ) self.http_request_factory = HttpRequestFactory() - self.allowed_endpoints = None # type: Optional[List[Pattern]] + self.allowed_endpoints: Optional[List[Pattern[str]]] = None allowed_endpoints = self.get_config("allowed_endpoints", list) if allowed_endpoints: self.allowed_endpoints = list(map(glob_to_regex, allowed_endpoints)) @@ -150,6 +150,17 @@ async def _dispatch_notification_unlimited( endpoint = device.data.get("endpoint") auth = device.data.get("auth") + + if not p256dh or not isinstance(endpoint, str) or not isinstance(auth, str): + logger.warn( + "Rejecting pushkey; subscription info incomplete or invalid " + + "(p256dh: %s, endpoint: %r, auth: %r)", + p256dh, + endpoint, + auth, + ) + return [device.pushkey] + endpoint_domain = urlparse(endpoint).netloc if self.allowed_endpoints: allowed = any( @@ -163,16 +174,6 @@ async def _dispatch_notification_unlimited( # abort, but don't reject push key return [] - if not p256dh or not endpoint or not auth: - logger.warn( - "Rejecting pushkey; subscription info incomplete " - + "(p256dh: %s, endpoint: %s, auth: %s)", - p256dh, - endpoint, - auth, - ) - return [device.pushkey] - subscription_info = { "endpoint": endpoint, "keys": {"p256dh": p256dh, "auth": auth}, @@ -289,7 +290,7 @@ def _handle_response( response: IResponse, response_text: str, pushkey: str, - endpoint_domain: bytes, + endpoint_domain: str, ) -> bool: """ Logs and determines the outcome of the response