custom_components/bahmcloud_store/views.py aktualisiert
This commit is contained in:
@@ -9,7 +9,7 @@ from aiohttp import web
|
|||||||
from homeassistant.components.http import HomeAssistantView
|
from homeassistant.components.http import HomeAssistantView
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .core import BCSCore # typing only, avoids runtime circular import
|
from .core import BCSCore # typing only
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -18,8 +18,10 @@ class StaticAssetsView(HomeAssistantView):
|
|||||||
url = "/api/bahmcloud_store_static/{path:.*}"
|
url = "/api/bahmcloud_store_static/{path:.*}"
|
||||||
name = "api:bahmcloud_store_static"
|
name = "api:bahmcloud_store_static"
|
||||||
|
|
||||||
# RESTORE previous behavior: require HA auth (this worked for you before)
|
# CRITICAL:
|
||||||
requires_auth = True
|
# Panel static files (JS/CSS/HTML) must be accessible without auth.
|
||||||
|
# Otherwise module loads can fail behind proxies/clients and trigger HA's ban middleware.
|
||||||
|
requires_auth = False
|
||||||
|
|
||||||
async def get(self, request: web.Request, path: str) -> web.Response:
|
async def get(self, request: web.Request, path: str) -> web.Response:
|
||||||
base = Path(__file__).resolve().parent / "panel"
|
base = Path(__file__).resolve().parent / "panel"
|
||||||
@@ -39,9 +41,10 @@ class StaticAssetsView(HomeAssistantView):
|
|||||||
target = (target / "index.html").resolve()
|
target = (target / "index.html").resolve()
|
||||||
|
|
||||||
if not target.exists():
|
if not target.exists():
|
||||||
|
_LOGGER.error("BCS static asset not found: %s", target)
|
||||||
return web.Response(status=404)
|
return web.Response(status=404)
|
||||||
|
|
||||||
# aiohttp: charset must NOT be included in content_type string
|
# aiohttp: do NOT include charset in content_type string
|
||||||
content_type = "text/plain"
|
content_type = "text/plain"
|
||||||
charset = None
|
charset = None
|
||||||
|
|
||||||
@@ -59,7 +62,12 @@ class StaticAssetsView(HomeAssistantView):
|
|||||||
elif target.suffix == ".png":
|
elif target.suffix == ".png":
|
||||||
content_type = "image/png"
|
content_type = "image/png"
|
||||||
|
|
||||||
return web.Response(body=target.read_bytes(), content_type=content_type, charset=charset)
|
resp = web.Response(body=target.read_bytes(), content_type=content_type, charset=charset)
|
||||||
|
|
||||||
|
# Development friendly (prevents stale cached panel.js)
|
||||||
|
resp.headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
|
||||||
|
resp.headers["Pragma"] = "no-cache"
|
||||||
|
return resp
|
||||||
|
|
||||||
|
|
||||||
class BCSApiView(HomeAssistantView):
|
class BCSApiView(HomeAssistantView):
|
||||||
@@ -72,11 +80,7 @@ class BCSApiView(HomeAssistantView):
|
|||||||
|
|
||||||
async def get(self, request: web.Request) -> web.Response:
|
async def get(self, request: web.Request) -> web.Response:
|
||||||
return web.json_response(
|
return web.json_response(
|
||||||
{
|
{"ok": True, "version": self.core.version, "repos": self.core.list_repos_public()}
|
||||||
"ok": True,
|
|
||||||
"version": self.core.version,
|
|
||||||
"repos": self.core.list_repos_public(),
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async def post(self, request: web.Request) -> web.Response:
|
async def post(self, request: web.Request) -> web.Response:
|
||||||
@@ -128,22 +132,17 @@ class BCSReadmeView(HomeAssistantView):
|
|||||||
if not md:
|
if not md:
|
||||||
return web.json_response({"ok": False, "message": "README not found."}, status=404)
|
return web.json_response({"ok": False, "message": "README not found."}, status=404)
|
||||||
|
|
||||||
|
# For now keep html best-effort (we will perfect it after the store is stable again)
|
||||||
html = None
|
html = None
|
||||||
|
|
||||||
# Best-effort: if HA provides a markdown renderer util, we use it.
|
|
||||||
try:
|
try:
|
||||||
from homeassistant.util.markdown import async_render_markdown # type: ignore
|
from homeassistant.util.markdown import async_render_markdown # type: ignore
|
||||||
|
|
||||||
html = await async_render_markdown(self.core.hass, md)
|
html = await async_render_markdown(self.core.hass, md)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_LOGGER.debug("Markdown render failed: %s", e)
|
_LOGGER.debug("Markdown render failed: %s", e)
|
||||||
html = None
|
|
||||||
|
|
||||||
# Best-effort sanitization if available
|
|
||||||
if html:
|
if html:
|
||||||
try:
|
try:
|
||||||
from homeassistant.util.sanitize_html import async_sanitize_html # type: ignore
|
from homeassistant.util.sanitize_html import async_sanitize_html # type: ignore
|
||||||
|
|
||||||
html = await async_sanitize_html(self.core.hass, html)
|
html = await async_sanitize_html(self.core.hass, html)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_LOGGER.debug("HTML sanitize not available/failed: %s", e)
|
_LOGGER.debug("HTML sanitize not available/failed: %s", e)
|
||||||
|
|||||||
Reference in New Issue
Block a user