mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 08:00:32 +02:00
Add Steam screenshots, Tailscale remote access, VR-video fixes
- Screenshots: list the Frame's Steam screenshots, open them in the viewer, and save new ones to ~/Pictures/SteamFrame. Ids are validated before any shell, and copies land atomically. - Tailscale: scripts/tailscale-on-frame.sh installs a userspace tailscaled as a lingering systemd --user service with no sudo, SHA-256 checked, safe to re-run, with --uninstall. docs/tailscale.md covers setup and warns that in userspace mode every Frame port, including loopback-only DevTools and ADB, is reachable from the tailnet. - push-vr-video.sh: filenames starting with "-" are safe, symlinks are followed, and a real Videos\VR directory triggers a warning. - Tests cover the screenshot routes (19 total). Docs keep placeholder addresses for the headset and tailnet. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
99653151c4
commit
eabf4cd1f9
10 files changed
+427
-54
No files matched your search
@@ -15,6 +15,7 @@ import tempfile
|
||||
import time
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from urllib.parse import quote
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
|
||||
@@ -81,6 +82,8 @@ class ServerGuards(unittest.TestCase):
|
||||
# <img src> and plain form posts from other sites can't set it.
|
||||
self.assertEqual(self.request("GET", "/api/status")[0], 403)
|
||||
self.assertEqual(self.request("GET", "/api/screenshot?view=headset")[0], 403)
|
||||
self.assertEqual(self.request("GET", "/api/shots")[0], 403)
|
||||
self.assertEqual(self.request("GET", "/api/shots/image?id=1/250820/20260925225208_1.jpg")[0], 403)
|
||||
self.assertEqual(self.request("POST", "/api/launch", {"appid": "620"})[0], 403)
|
||||
|
||||
def test_captures_are_not_cacheable(self):
|
||||
@@ -98,11 +101,21 @@ class ServerGuards(unittest.TestCase):
|
||||
("/api/volume", {"level": 1.5}),
|
||||
("/api/clipboard", {"text": ""}),
|
||||
("/api/open", {"what": "anything-else"}),
|
||||
("/api/shots/save", {"ids": []}),
|
||||
("/api/shots/save", {"ids": "1/250820/20260925225208_1.jpg"}),
|
||||
("/api/shots/save", {"ids": [1]}),
|
||||
("/api/shots/save", {"ids": ["1/250820/../../.ssh/id_ed25519"]}),
|
||||
("/api/shots/save", {"ids": ["1/250820/20260925225208_1.jpg; rm -rf ~"]}),
|
||||
]
|
||||
for path, body in cases:
|
||||
status, payload = self.post(path, body)
|
||||
self.assertEqual(status, 400, f"{path} {body} -> {payload}")
|
||||
|
||||
def test_screenshot_ids_checked_before_ssh(self):
|
||||
for shot in ("../../etc/passwd", "1/250820/x.jpg", "1/2/20260925225208_1.jpg;id", "1/250820/20260925225208_1.gif"):
|
||||
status, _, _ = self.request("GET", f"/api/shots/image?id={quote(shot)}", headers={"X-Frame-UI": "1"})
|
||||
self.assertEqual(status, 400, shot)
|
||||
|
||||
def test_bad_bodies(self):
|
||||
conn = http.client.HTTPConnection("127.0.0.1", self.port, timeout=10)
|
||||
conn.request("POST", "/api/launch", body=b"{not json", headers={"X-Frame-UI": "1"})
|
||||
|
||||
Reference in new issue
Block a user