diff --git a/src/bggpipe/static/apple-touch-icon.png b/src/bggpipe/static/apple-touch-icon.png new file mode 100644 index 0000000..cdbfecb Binary files /dev/null and b/src/bggpipe/static/apple-touch-icon.png differ diff --git a/src/bggpipe/templates/shell.html b/src/bggpipe/templates/shell.html index 22fde12..0d9385c 100644 --- a/src/bggpipe/templates/shell.html +++ b/src/bggpipe/templates/shell.html @@ -5,6 +5,8 @@ <!--TITLE--> + + diff --git a/src/bggpipe/webreview.py b/src/bggpipe/webreview.py index 81e821f..41ef90b 100644 --- a/src/bggpipe/webreview.py +++ b/src/bggpipe/webreview.py @@ -1089,8 +1089,19 @@ def create_app( "logo.jpg": "image/jpeg", "logo-full.jpg": "image/jpeg", "favicon.png": "image/png", + "apple-touch-icon.png": "image/png", } + @app.get("/apple-touch-icon.png") + @app.get("/apple-touch-icon-precomposed.png") + def apple_touch_icon() -> Response: + # iOS probes these root paths (cookie-less) when saving to the + # home screen; the guard already treats them as public + data = ( + resources.files("bggpipe") / "static" / "apple-touch-icon.png" + ).read_bytes() + return Response(content=data, media_type="image/png") + @app.get("/static/{name}") def static_asset(name: str) -> Response: media_type = _STATIC.get(name) # allowlist: no traversal possible diff --git a/tests/test_webreview.py b/tests/test_webreview.py index 774c753..70f3f7b 100644 --- a/tests/test_webreview.py +++ b/tests/test_webreview.py @@ -1048,3 +1048,14 @@ def test_lan_403_is_html_for_navigations(tmp_path): res = phone.get("/titles", headers={"accept": "text/html,application/xhtml+xml"}) assert res.status_code == 403 assert "access key needed" in res.text # a person sees prose, not JSON + + +def test_home_screen_icon_is_served_and_public(tmp_path): + cfg = make_cfg(tmp_path) + app = create_app(cfg, client=unauthorized_client(tmp_path), lan_token="sekret") + phone = TestClient(app, base_url="http://192.168.1.99:8377") + # iOS probes cookie-less; both the root probe and the linked path work + assert phone.get("/apple-touch-icon.png").status_code == 200 + assert phone.get("/static/apple-touch-icon.png").status_code == 200 + page = phone.get("/?k=sekret", follow_redirects=True) + assert 'rel="apple-touch-icon"' in page.text