Skip to content

fix(runtime): apply TypeScript core external_links policy - #371

Open
yusufesse wants to merge 1 commit into
vercel-labs:mainfrom
yusufesse:fix/ts-core-external-links
Open

fix(runtime): apply TypeScript core external_links policy#371
yusufesse wants to merge 1 commit into
vercel-labs:mainfrom
yusufesse:fix/ts-core-external-links

Conversation

@yusufesse

@yusufesse yusufesse commented Aug 16, 2026

Copy link
Copy Markdown

Summary

  • TypeScript cores never copied app.zon security.navigation.external_links into runWithOptions, so the policy stayed at the deny-by-default empty allowlist.
  • Cmd.openExternalUrl is then rejected as NavigationDenied. The host send is fire-and-forget (catch {}), so allowed HTTP(S) URLs never open a system browser and the app shows no error.
  • Zig cores already pass this field. The TypeScript runner now reads action and allowed_urls from the manifest the same way it already reads navigation origins.

Docs already describe this gate (https://native-sdk.dev/security). Wildcard patterns must end in * and include a / after the host (https://example.com/* is valid; https://example.com* is not).

Test plan

  • zig build test and zig build validate (root suites from scripts/gate.sh fast)
  • zig build test-examples-frontends and the render bench-check
  • npm ci --include=dev in packages/core, then zig build test-examples-native
  • zig build test-example-kanban and zig build test-example-gpu-components (compile the staged TypeScript runner against real app.zon manifests that set external_links.action = "deny")
  • Compile the same TypeScript runner with .external_links = .{ .action = "open_system_browser", .allowed_urls = .{ "https://example.com/*" } } (temporary local app.zon only; not committed). This is the path native check does not compile.
  • Existing root tests already cover allow/deny once the policy is on the runtime: allowsExternalUrl matcher rules, and openExternalUrl succeeding for https://example.com/docs / failing for a non-matching URL on the null platform
  • Live desktop confirmation on this branch (temporary uncommitted examples/chatbot harness): open_system_browser + https://example.com/* opened the system browser to https://example.com/docs; .action = "deny" on the same button opened nothing and showed no error
  • node --test packages/core/test/services.test.ts and packages/core/test/surface_tools.test.ts (gate-mapped for src/**; not specific to this wiring)

scripts/gate.sh fast also mapped examples-mobile; that step fails on this machine (no Apple iOS SDK) and does not compile ts_core_main.zig.

TypeScript cores never copied app.zon security.navigation.external_links
into runWithOptions, so Cmd.openExternalUrl stayed deny-by-default and
failed silently.
@vercel

vercel Bot commented Aug 16, 2026

Copy link
Copy Markdown

@yusufesse is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

@yusufesse

Copy link
Copy Markdown
Author

Verified locally on this branch with a temporary (uncommitted) TypeScript examples/chatbot harness:

  • app.zon set to .external_links = .{ .action = "open_system_browser", .allowed_urls = .{ "https://example.com/*" } } and a button that issues Cmd.openExternalUrl("https://example.com/docs"). NATIVE_SDK_PATH pointed at this checkout; native dev; button click opened the system browser to https://example.com/docs.
  • Same button with .action = "deny": click did nothing and showed no error. That is the pre-fix TypeScript-runner failure mode (NavigationDenied swallowed by the fire-and-forget host send).

The example edits were local only and are not part of this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant