329 files

This commit is contained in:
Home Assistant Version Control
2026-08-06 13:56:25 +00:00
parent 0df89406fa
commit 7afe7add1d
330 changed files with 13098 additions and 5942 deletions
@@ -19,6 +19,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.event import async_track_time_change
from .const import (
DEFAULT_NOTIFICATION_NAV_URL,
NOTIF_TYPE_ALL_CHORES_DONE,
NOTIF_TYPE_BADGE_EARNED,
NOTIF_TYPE_BEDTIME_REMINDER,
@@ -88,6 +89,27 @@ NOTIFICATION_TYPES_BY_ID: dict[str, NotificationTypeMeta] = {
}
def _validate_nav_url(value: str) -> str:
"""Normalise and vet a notification tap target.
The tap target is opened on the *recipient's* device, so only dashboard
paths, web URLs and the companion app's noAction sentinel are allowed —
never intent:// / app:// / homeassistant:// style deep links.
"""
value = (value or "").strip()
if value in ("", "noAction"):
return value
if value.lower().startswith(("http://", "https://")):
return value
if (
value.startswith("/")
and not value.startswith("//")
and not any(ord(c) <= 32 or ord(c) == 127 for c in value)
):
return value
raise ValueError("nav_url must be a /path, an http(s) URL, or noAction")
def _parse_hhmm(value: str) -> tuple[int, int] | None:
"""Parse "HH:MM" into (hour, minute); None if blank/malformed."""
if not value:
@@ -315,7 +337,11 @@ class NotificationCoordinator:
per_type = (getattr(cfg, "nav_url", "") or "").strip()
if per_type:
return per_type
return str(self.storage.get_setting("notification_nav_url", "/taskmate") or "").strip()
return str(
self.storage.get_setting(
"notification_nav_url", DEFAULT_NOTIFICATION_NAV_URL
) or ""
).strip()
def _resolve_notify_service(self, recipient_id: str) -> str:
if recipient_id.startswith("child:"):
@@ -711,8 +737,10 @@ class NotificationCoordinator:
async def set_nav_url(self, type_id: str | None, nav_url: str) -> None:
"""Set the tap target — global (type_id falsy) or per notification type."""
nav_url = (nav_url or "").strip()
nav_url = _validate_nav_url(nav_url)
if type_id:
if type_id not in NOTIFICATION_TYPES_BY_ID:
raise ValueError(f"Unknown notification type {type_id}")
self.storage.set_notification_nav_url(type_id, nav_url)
else:
self.storage.set_setting("notification_nav_url", nav_url)