Files
openclaw/apps/macos/Sources/OpenClaw/NodeMode/MacNodeCanvasHostedSurfaceResolver.swift
Peter Steinberger c6dc5bc764 fix(canvas): hosted pages fail on macOS with scoped Gateway auth (#105336)
* fix(canvas): harden hosted Canvas on macOS

Resolve Gateway-hosted Canvas and A2UI targets through refreshed node capabilities, keep bridge and live-reload behavior correct, and restrict native action dispatch to the exact trusted main-frame document.

Preserve scalar evaluation results, secure action IDs, and hidden state-directory watching.

Co-authored-by: GuoJiaming <804436395@qq.com>
Co-authored-by: Lucenx9 <185146821+Lucenx9@users.noreply.github.com>
Co-authored-by: zeng-weihan <ceng.weihan@xydigit.com>

* chore(canvas): defer release note

* chore(canvas): refresh native i18n inventory

* refactor(canvas): isolate hosted surface resolution

---------

Co-authored-by: GuoJiaming <804436395@qq.com>
Co-authored-by: Lucenx9 <185146821+Lucenx9@users.noreply.github.com>
Co-authored-by: zeng-weihan <ceng.weihan@xydigit.com>
2026-07-12 13:02:27 +01:00

43 lines
1.7 KiB
Swift

import Foundation
struct MacNodeCanvasHostedSurfaceResolver: Sendable {
private let currentSurfaceURL: @Sendable () async -> String?
private let refreshSurfaceURL: @Sendable () async -> String?
init(
currentSurfaceURL: @escaping @Sendable () async -> String?,
refreshSurfaceURL: @escaping @Sendable () async -> String?)
{
self.currentSurfaceURL = currentSurfaceURL
self.refreshSurfaceURL = refreshSurfaceURL
}
func resolveA2UIURL(forceRefresh: Bool = false) async -> String? {
if !forceRefresh,
let currentSurface = await currentSurfaceURL(),
let current = CanvasHostedURLResolver.resolveA2UIURL(surfaceURL: currentSurface)
{
return current
}
let refreshedSurface = await refreshSurfaceURL()
return CanvasHostedURLResolver.resolveA2UIURL(surfaceURL: refreshedSurface)
}
func resolveTarget(_ target: String?) async throws -> CanvasHostedTarget? {
guard let target, CanvasHostedURLResolver.isHostedTarget(target) else { return nil }
if let refreshedSurface = await refreshSurfaceURL(),
let resolved = CanvasHostedURLResolver.resolve(surfaceURL: refreshedSurface, target: target)
{
return resolved
}
if let currentSurface = await currentSurfaceURL(),
let resolved = CanvasHostedURLResolver.resolve(surfaceURL: currentSurface, target: target)
{
return resolved
}
throw NSError(domain: "Canvas", code: 32, userInfo: [
NSLocalizedDescriptionKey: "CANVAS_HOST_NOT_CONFIGURED: gateway did not advertise canvas host",
])
}
}