Repository navigation
fix(studio): secrets stay in Go; file verbs check their roots - #516
Merged
Merged
Conversation
…le checks roots Stored keys are reported by presence only, WiFi tokens are no longer remembered, and RunFile checks the workspace and automation roots. GetAPIKey reports whether a key is saved and never returns it. The key panel starts with an empty field, and an empty save no longer clears a saved key; Remove key still deletes. WiFi tokens are no longer remembered. The token is typed for each connection. The saved tag and the forget control are gone, and Studio deletes the plain-text copy an earlier version kept in localStorage on first start. The host and port are still remembered. RunFile accepts only .probe files inside the open workspace or an automation folder: the check the automation endpoint makes. RunFileAsync makes it before the background start, so a refusal reaches the caller. Tests cover the API key presence check, the run path refusals, and the RunFileAsync refusal. The studio_run_file description and the Studio docs say what changed.
ReadFile reads .probe files only. The editor calls it only for the .probe entries of the open workspace tree, and the automation endpoint calls it only on a path it has already checked, so that call is unchanged. It now checks the path the way RunFile does: an absolute path, resolved through every symlink, inside the workspace a person opened or an automation folder, and a regular .probe file. A ".." segment is refused before anything else, on either separator, including one that would stay inside the workspace. Tests cover a file inside and outside the workspace, a non-.probe file, a ".." path that climbs out and one that stays inside, a relative path, and a symlink that points out. The round-trip and headless tests now open the workspace first, as the page does.
…le follow Studio file access now has one rule. WriteFile saves .probe files, and creates the folders above them, only inside the workspace a person opened or an automation folder. ListDir lists only folders inside those roots. With no workspace open it lists nothing, and a folder that does not exist yet lists as empty. Both use the helper that ReadFile, RunFile and the automation endpoint already use, so the rule lives in one place (resolveInRoots). It refuses a relative path, a ".." segment on either separator, and any path whose symlinks resolve outside the roots. For writes it also resolves the nearest existing folder, so a new file under a folder that is a link out is refused, and a folder named like a .probe file is refused as a target. The automation endpoint's open_workspace and list_dir use the same helper, so they now refuse ".." as well. The file tree's up button stops at the workspace root. Tests cover a new file inside the workspace, outside paths, a non-.probe name, ".." on both separators, a file and a new file under a link out, a relative path, a folder named like a probe file, the workspace listing with hidden entries left out, a missing folder, folders outside, and no workspace open. The existing ListDir and round-trip tests open the workspace first, as the page does. Not covered: LoadWorkspaceSettings and SaveWorkspaceSettings still take a folder and read or write probe.yaml in it without this check. They need the UI call order checked, and the browser suite runs only in CI.
A discovered device's WiFi token is saved in the platform keychain under the device's name, so the next connection needs no paste. ConnectWiFiSaved reads the token in Go, and the window never receives it. A token is saved only after ConnectWiFi accepts it. The plain-text copy an earlier version kept in localStorage is deleted on start. Tests cover the per-device round trip, refusal of an empty device name or token, and that ConnectWiFiSaved runs the same target checks as ConnectWiFi.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
.probefiles inside the open workspace or an automation folder. Paths with..and symlinks that leave the root are refused.mainis merged into the branch, so it is current with the latest changes.Test plan
go test ./...instudio. New tests cover the per-device keychain round trip, refusal of an empty device name or token, and that a saved token goes through the same target checks as a typed one.go vet ./...instudionpm run build,typecheck:device-view,test:device-view(116),test:probescript(11),check:probescriptCLAUDE_CODE_OAUTH_TOKEN🤖 Generated with Claude Code