fix: preserve iframe plugin chat mode

This commit is contained in:
Rocky Kwok committed 2026-07-28 11:03:28 +08:00
1 parent bd8ec41914
commit 008c9ede6e
3 files changed
+50 -20

No files matched your search

@@ -45,14 +45,37 @@ test("requires an explicit chatMode=iframe opt-in for the Brainy page", () => {
assert.equal(isExplicitBrainyIframeMode("chatMode=IFRAME"), true);
});
test("redirects accidental chats_iframe routes to standard full chat", () => {
test("upgrades legacy iframe-source routes to the iframe protocol", () => {
assert.equal(
resolveStandardChatFallback(
"/page/workspace/chats_iframe/new",
"?from=iframe&hideChrome=1",
),
"/page/workspace/chats/new?hideChrome=1&chatMode=full",
"/page/workspace/chats_iframe/new?from=iframe&hideChrome=1&chatMode=iframe",
);
});
test("honors an explicit chat mode over the legacy iframe source", () => {
assert.equal(
resolveStandardChatFallback(
"/page/workspace/chats_iframe/new",
"?from=iframe&chatMode=full",
),
"/page/workspace/chats/new?chatMode=full",
);
});
test("treats a blank chat mode as absent for the legacy iframe source", () => {
assert.equal(
resolveStandardChatFallback(
"/page/workspace/chats_iframe/new",
"?from=iframe&chatMode=%20%20",
),
"/page/workspace/chats_iframe/new?from=iframe&chatMode=iframe",
);
});
test("redirects chats_iframe routes without the iframe source to standard full chat", () => {
assert.equal(
resolveStandardChatFallback(
"/page/workspace/chats_iframe/thread-123",
@@ -121,17 +144,17 @@ test("forces the iframe theme on the login route without changing normal login",
test("preserves the iframe theme in the post-login redirect", () => {
assert.equal(
buildChatsIframeRedirectPath("?from=iframe&theme=dark-blue"),
"/page/workspace/chats_iframe/new?from=iframe&theme=dark-blue",
"/page/workspace/chats_iframe/new?from=iframe&chatMode=iframe&theme=dark-blue",
);
assert.equal(
buildChatsIframeRedirectPath("?from=iframe"),
"/page/workspace/chats_iframe/new?from=iframe",
"/page/workspace/chats_iframe/new?from=iframe&chatMode=iframe",
);
assert.equal(
buildChatsIframeRedirectPath(
"?from=iframe&theme=dark-blue&ticket=secret&authToken=secret",
),
"/page/workspace/chats_iframe/new?from=iframe&theme=dark-blue",
"/page/workspace/chats_iframe/new?from=iframe&chatMode=iframe&theme=dark-blue",
);
});
@@ -141,7 +164,7 @@ test("keeps the iframe redirect ahead of login-method fallbacks", () => {
"?from=iframe&theme=dark-blue&yUserId=user-1",
"/page/workspace/chats/new",
),
"/page/workspace/chats_iframe/new?from=iframe&theme=dark-blue",
"/page/workspace/chats_iframe/new?from=iframe&chatMode=iframe&theme=dark-blue",
);
assert.equal(
resolvePostLoginRedirectPath("?yUserId=user-1", "/page/workspace/chats/new"),
@@ -156,7 +179,7 @@ test("preserves iframe theme when a new chat becomes a thread", () => {
"thread-123",
"?from=iframe&theme=dark-blue&ticket=secret",
),
"/page/workspace/chats_iframe/thread-123?from=iframe&theme=dark-blue",
"/page/workspace/chats_iframe/thread-123?from=iframe&chatMode=iframe&theme=dark-blue",
);
});
@@ -23,7 +23,13 @@ export function buildChatsIframeRedirectPath(search: string): string {
target.set("from", IFRAME_LOGIN_SOURCE);
}
if (isExplicitBrainyIframeMode(search)) {
const requestedMode = source.get("chatMode")?.trim();
if (requestedMode) {
target.set("chatMode", requestedMode);
} else if (isChatsIframeLogin(search)) {
// Plugin links historically identify this protocol with `from=iframe`.
// Normalize that legacy marker into the explicit mode before handing the
// URL to the workspace route, so it does not fall back to the full chat.
target.set("chatMode", "iframe");
}
@@ -89,21 +95,25 @@ export function resolveStandardChatFallback(
pathname: string,
search: string,
): string | null {
if (
!isChatsIframeWorkspacePath(pathname) ||
isExplicitBrainyIframeMode(search)
) {
if (!isChatsIframeWorkspacePath(pathname) || isExplicitBrainyIframeMode(search)) {
return null;
}
const normalizedSearch = search.startsWith("?") ? search.slice(1) : search;
const params = new URLSearchParams(normalizedSearch);
const requestedMode = params.get("chatMode")?.trim();
if (isChatsIframeLogin(search) && !requestedMode) {
params.set("chatMode", "iframe");
const targetSearch = params.toString();
return targetSearch ? `${pathname}?${targetSearch}` : pathname;
}
const routePrefix = "/page/workspace/chats_iframe/";
const routeSuffix = pathname.slice(routePrefix.length);
const targetPath =
routeSuffix && routeSuffix !== "new"
? `/page/workspace/chats/${routeSuffix}`
: "/page/workspace/chats/new";
const normalizedSearch = search.startsWith("?") ? search.slice(1) : search;
const params = new URLSearchParams(normalizedSearch);
params.delete("from");
params.set("chatMode", "full");
const targetSearch = params.toString();
+3 -6
View File
@@ -76,7 +76,6 @@ function summarizeStoredUserInfo(): Record<string, unknown> | null {
}
const DEFAULT_USERNAME = 'guest';
const IFRAME_LOGIN_SOURCE = 'iframe';
const IFRAME_CHAT_MODE = 'iframe';
const DEFAULT_REDIRECT_PATH = '/page/workspace/chats/new';
const FULL_CHAT_MODE = 'full';
@@ -104,15 +103,13 @@ export default function LoginPage() {
searchParams.get('chatMode')?.trim().toLowerCase() ?? '';
const brainyIframeRequested = requestedChatMode === IFRAME_CHAT_MODE;
// Wujie is an application container, not the Brainy iframe protocol. It
// must therefore land on the regular full ChatPage. Legacy `from=iframe`
// links now do the same; only the explicit `chatMode=iframe` protocol opt-in
// is allowed to open IframeChatPage.
// must therefore land on the regular full ChatPage. Plugin links with
// `from=iframe` are normalized into the explicit iframe protocol mode.
const fullChatRequested = useMemo(
() =>
!brainyIframeRequested &&
(isWujieEnv() ||
requestedChatMode === FULL_CHAT_MODE ||
searchParams.get('from') === IFRAME_LOGIN_SOURCE),
requestedChatMode === FULL_CHAT_MODE),
[brainyIframeRequested, requestedChatMode, searchParams],
);
const isIframeLogin = useMemo(