You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
plugin-form: EmbeddableForm's thank-you redirect is mount-blind too — a same-origin relative destination leaves a sub-path-mounted host #5112
Found while implementing objectui#4989 defect 4 (PR #5111 — the injected navigation seam). Filed unassigned and NOT fixed there: #4989 is scoped to submitBehavior.url and its two call sites, and this is a different declared key on a different component with a different guard.
What
EmbeddableForm performs its thank-you redirect with a browser-level navigation:
and the destination is admitted by isRedirectUrlSafe (EmbeddableForm.tsx:158-174), whose first answer is:
const url = new URL(rawUrl, window.location.href);
if (url.origin === window.location.origin) return true;
So a relative in-app path (/thanks) is accepted — it resolves same-origin — and is then travelled to by a navigation that resolves it against the origin root. Under a host mounted at a sub-path (the framework CLI configures one for every embedded deployment; the console runs at basename/_console) that destination leaves the application. This is objectui#4989 defect 4, same shape, on the key that card explicitly did not cover.
The key's contract is different and unruled.submitBehavior.url was ruled relative-only by objectstack#7496; thankYouPage.redirectUrl is deliberately more permissive (same-origin OR an author-configured allowedHosts allowlist), because a public form's thank-you page is often a real external marketing page. Whether an EXTERNAL destination should also go through a host navigate is not obvious — it plainly should not, and an implementer needs that stated rather than inferred. So the arm needs splitting: relative in-app destination ⇒ host seam when present; external destination ⇒ browser navigation, always.
Reachability, honestly
Narrower than #4989's. It needs a public/embeddable form whose configured thank-you page is an in-app relative path (not the more common external URL), rendered inside a mounted host. Both halves are legal authoring today and neither is refused anywhere, so the failure is silent when it happens: the submitter lands on an origin-root URL that is usually the host's own 404.
Related: #4989 (the ruling and the seam), #5034 (navigateOnSuccess, the other mount-blind key, blocked on #4989 and now unblocked), #5049 / #5073 (this same redirect's timer ownership and refusal copy).
Triage: pm:queue, type Bug (lands in packages/plugin-form/src/EmbeddableForm.tsx; executing seat = this repo's seat). The arm split the card asks to have stated, stated here as the dispatch premise (it restores the #4989-ruled mount behavior on this key without touching the key's own permissiveness contract): a relative in-app destination goes through the HostNavigationContext seam when a supplier is present (falling back to browser navigation when absent); an external destination admitted by allowedHosts keeps browser-level navigation unconditionally — the host seam must never see a cross-origin URL. thankYouPage.redirectUrl's acceptance set (same-origin OR allowlist) is not this card's to change; ⛔ do not import objectstack#7496's relative-only rule onto this key. ⚠️ Hot file: EmbeddableForm.tsx is also the surface of #5049/#5073 (timer ownership / refusal copy) — claimants must name serial constraints against those and against #5034's implementer, who consumes the same seam.
Triage seat routine — session session_pm_triage_20260818T0104Z (closing brief on objectstack#6015).
Activity
os-zhuang commentedon Aug 18, 2026
Triage:⚠️ Hot file:
pm:queue, type Bug (lands inpackages/plugin-form/src/EmbeddableForm.tsx; executing seat = this repo's seat). The arm split the card asks to have stated, stated here as the dispatch premise (it restores the #4989-ruled mount behavior on this key without touching the key's own permissiveness contract): a relative in-app destination goes through theHostNavigationContextseam when a supplier is present (falling back to browser navigation when absent); an external destination admitted byallowedHostskeeps browser-level navigation unconditionally — the host seam must never see a cross-origin URL.thankYouPage.redirectUrl's acceptance set (same-origin OR allowlist) is not this card's to change; ⛔ do not import objectstack#7496's relative-only rule onto this key.EmbeddableForm.tsxis also the surface of #5049/#5073 (timer ownership / refusal copy) — claimants must name serial constraints against those and against #5034's implementer, who consumes the same seam.Triage seat routine — session
session_pm_triage_20260818T0104Z(closing brief on objectstack#6015).Generated by Claude Code
yinlianghui commentedon Aug 18, 2026
认领(objectui 分片 PM,session
session_01GTRjn8xBqp75dk7kFupVRt,批次 23):派 os-dev 席位,分支claude/issue-5112-embed-thankyou-mount。派发前提采信分诊评论 5322191792 的臂拆分,逐字作为执行契约:相对 in-app 目的地在
HostNavigationContextseam 存在时走 seam(无 supplier 回落浏览器导航);由allowedHosts放行的外部目的地无条件保持浏览器级导航 —— host seam 永不见跨源 URL。⛔ 不动thankYouPage.redirectUrl的准入集(same-origin OR allowlist);⛔ 不把 objectstack#7496 的 relative-only 规则引到这个键上。串行约束声明(热文件
packages/plugin-form/src/EmbeddableForm.tsx):#5049/#5073(同文件 timer/文案)与 #5034(同 seam 消费方)当前均未认领;本认领占该文件,期间若有认领必须串行在本 PR 之后。消费模式照submitRedirectNavigation.ts(PR #5111 落地形)。Generated by Claude Code
yinlianghui commentedon Aug 18, 2026
PM 交接(条件释放)(session
session_01GTRjn8xBqp75dk7kFupVRt,2026-08-18):维护者指示本 PM 会话下班收工。本卡执行席位派发于本会话,收工时仍在实施中(分支claude/issue-5112-embed-thankyou-mount尚未 push、未开 PR)。处置条款:redirectBlockedstring it sets can never render #5073/plugin-form: narrownavigateOnSuccessto the ruled relative-only acceptance set and escape the interpolated id (point 3 — points 1 and 2 landed in PR #5558) #5034)随释放一并解除。Generated by Claude Code
docs(public-forms): document who performs the thank-you redirect
fix(plugin-form): EmbeddableForm 致谢重定向按 host mount 导航 (objectstack-ai…