From adbb0e0dc4c0b8a5cf97b9be736490453631df03 Mon Sep 17 00:00:00 2001 From: lsdsjy <1356263+lsdsjy@users.noreply.github.com> Date: Tue, 22 Sep 2026 11:39:14 +0800 Subject: [PATCH 1/3] fix(client): update the contact form URL and drop its account UID prefill The Contact us entry now opens the current Feishu questionnaire, and the URL no longer carries the signed-in account UID: contactUs stops reading the account profile, contactUrl stops writing prefill_uid and hide_uid, and the remaining build and browser context fields keep their existing behavior. The url, package tests and the bilingual README and account-login note state the same current facts. --- ...026-09-14-deepseek-account-login.i18n.yaml | 4 ++-- .../2026-09-14-deepseek-account-login.md | 2 +- .../2026-09-14-deepseek-account-login.zh.md | 2 +- .../ui-settings-account/README.i18n.yaml | 4 ++-- packages/client/ui-settings-account/README.md | 2 +- .../client/ui-settings-account/README.zh.md | 2 +- .../src/client/contact-url.ts | 6 ++--- .../ui-settings-account/src/client/index.ts | 2 -- .../ui-settings-account/src/contact-config.ts | 2 +- .../tests/apply.client.spec.ts | 7 ++++-- .../tests/contact-url.client.spec.ts | 23 ++++++++++--------- 11 files changed, 28 insertions(+), 28 deletions(-) diff --git a/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.i18n.yaml index a97feda0c1..3d6874cde0 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.md -2026-09-14-deepseek-account-login.md: 65405b293cdea14a231d8d700589f9c3e7ef6db7 -2026-09-14-deepseek-account-login.zh.md: 0aca011826006a0fb8f0557464187b73da377238 +2026-09-14-deepseek-account-login.md: 9b323e03d6c60612092ac5834064770719d71560 +2026-09-14-deepseek-account-login.zh.md: ab50c4758de0567a96a59cfe8966e378d6b8de14 diff --git a/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.md b/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.md index 65405b293c..9b323e03d6 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.md +++ b/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.md @@ -36,7 +36,7 @@ The account plugin supplies choice, waiting, failure and timeout dialogs through Platform embedding transfers a grant from Host to Electron over private Node IPC and then once to the trusted Platform main frame through a sandboxed preload. Preload performs one synchronous IPC before page scripts execute; the main process only validates the sender and returns prepared memory. Platform reads the token synchronously thereafter without a readiness API. A failed initialization retains embedded mode and a throwing getter. Account UI projections remain credential-free. The Platform document can read this credential, so its script security is part of account protection; context isolation protects native capabilities, not a token intentionally returned to the document. Replacing or removing the grant destroys the document and its temporary session. -Support questionnaires receive only the Platform UID and available environment metadata through explicit prefill fields. Account tokens and masked contact details stay out of questionnaire URLs. The account provider projects the current-user UID for this purpose; the UI uses the latest account snapshot so sign-out cannot reuse a previous UID. +Support questionnaires receive only available environment metadata through explicit prefill fields. Account UIDs, tokens and masked contact details stay out of questionnaire URLs. Private proxy development can explicitly map authorization and completion URLs to platformOrigin with rewriteBrowserOrigin. Both pages retain their fixed paths and full query strings; allowing a remote origin without mapping it would send the browser outside the configured environment. Shipped configuration requires same-origin URLs. diff --git a/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.zh.md b/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.zh.md index 0aca011826..ab50c4758d 100644 --- a/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-14-deepseek-account-login.zh.md @@ -36,7 +36,7 @@ API Key 与账号记录独立保存。账号 token 没有过期或刷新流程 Platform 内嵌通过私有 Node IPC 将授权从 Host 传给 Electron,再经沙箱 preload 一次性传给受信任的 Platform 主 frame。preload 在页面脚本执行前执行一次同步 IPC;主进程仅校验调用来源并返回已准备的内存数据。Platform 此后同步读取 token,无需就绪接口。初始化失败时保留内嵌模式,由 getter 抛错。账号 UI 投影仍不包含凭证。Platform 文档能够读取此凭证,因此其脚本安全也是账号保护的一部分;上下文隔离保护原生能力,不能隐藏有意返回给文档的 token。替换或移除授权会销毁文档及其临时会话。 -支持问卷仅通过显式预填字段接收 Platform UID 和已有的环境信息,URL 不包含账号 token 或脱敏联系方式。账号提供者为此投影 current-user 的 UID;UI 使用最新账号快照,避免退出登录后复用旧 UID。 +支持问卷仅通过显式预填字段接收已有的环境信息,URL 不包含账号 UID、token 或脱敏联系方式。 私有代理开发可通过 rewriteBrowserOrigin 显式将授权页和完成页映射到 platformOrigin。两者保留固定路径和完整查询字符串;仅放宽来源而不做映射会让浏览器离开配置的环境。发布配置要求浏览器地址同源。 diff --git a/packages/client/ui-settings-account/README.i18n.yaml b/packages/client/ui-settings-account/README.i18n.yaml index cb697284a7..67f94258b5 100644 --- a/packages/client/ui-settings-account/README.i18n.yaml +++ b/packages/client/ui-settings-account/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-settings-account/README.md -README.md: fdbbc4c391e7b4d6f6111de936b23f2fa101f3e3 -README.zh.md: 64acaa4b975c5b37213990bb866b268c9a689d1e +README.md: 30d41fb49262619fd34f1bcd1abfec49d1248438 +README.zh.md: 1916bb2bb37704e5ecc22589620add82ce74780f diff --git a/packages/client/ui-settings-account/README.md b/packages/client/ui-settings-account/README.md index fdbbc4c391..30d41fb492 100644 --- a/packages/client/ui-settings-account/README.md +++ b/packages/client/ui-settings-account/README.md @@ -28,7 +28,7 @@ Balances use Platform Web currency formatting: two decimal places and digit grou Desktop usage and top-up actions open an isolated native Platform view below a 48px return bar. Back destroys the view and preserves the Account settings page. Browser clients retain external links. Loading failures retain the return action and show a centered localized error with Retry. Retry reloads the same destination; renderer commands never receive the account token. -Contact us opens the Feishu questionnaire in the system browser on Desktop or a new browser tab on Web. It supplies the available Platform UID, build version, UI locale and physical screen resolution as prefill_* parameters, with hide_*=1 for every context field; tokens and contact details are excluded. Configure contactFormUrl on the ui-settings-account plugin to select another HTTPS form. contactSource defaults to empty until the questionnaire supports a Harness source option; OS and device fields remain unfilled, matching the Web implementation. +Contact us opens the Feishu questionnaire in the system browser on Desktop or a new browser tab on Web. It supplies the available build version, UI locale and physical screen resolution as prefill_* parameters, with hide_*=1 for every context field; the account UID, tokens and contact details are excluded. Configure contactFormUrl on the ui-settings-account plugin to select another HTTPS form. contactSource defaults to empty until the questionnaire supports a Harness source option; OS and device fields remain unfilled, matching the Web implementation. The sidebar account menu uses the shared Menu surface, backdrop blur, spacing, and row typography; feature styles only size its launcher. diff --git a/packages/client/ui-settings-account/README.zh.md b/packages/client/ui-settings-account/README.zh.md index 64acaa4b97..1916bb2bb3 100644 --- a/packages/client/ui-settings-account/README.zh.md +++ b/packages/client/ui-settings-account/README.zh.md @@ -28,7 +28,7 @@ kind: "package-reference" Desktop 的用量和充值操作在 48px 返回栏下方打开隔离的原生 Platform 视图。返回操作销毁视图并保留 Account 设置页。浏览器客户端继续使用外链。加载失败时保留返回操作,居中显示本地化错误提示和“重试”按钮。重试重新加载同一目标页面;渲染进程命令不接收账号 token。 -“联系我们”在 Desktop 的系统浏览器或 Web 的新标签页打开飞书问卷。链接通过 prefill_* 参数填写已有的 Platform UID、构建版本、界面语言和屏幕物理分辨率,并为所有上下文字段设置 hide_*=1;不传 token 或联系方式。可在 ui-settings-account 插件配置 contactFormUrl,切换到另一个 HTTPS 问卷。问卷支持 Harness 来源选项前,contactSource 默认为空;OS 和设备字段沿用 Web 实现,保持未填写。 +“联系我们”在 Desktop 的系统浏览器或 Web 的新标签页打开飞书问卷。链接通过 prefill_* 参数填写已有的构建版本、界面语言和屏幕物理分辨率,并为所有上下文字段设置 hide_*=1;不传账号 UID、token 或联系方式。可在 ui-settings-account 插件配置 contactFormUrl,切换到另一个 HTTPS 问卷。问卷支持 Harness 来源选项前,contactSource 默认为空;OS 和设备字段沿用 Web 实现,保持未填写。 侧边栏账号菜单使用公共 Menu 的表面、背景模糊、间距和菜单项排版;功能样式仅设置入口布局。 diff --git a/packages/client/ui-settings-account/src/client/contact-url.ts b/packages/client/ui-settings-account/src/client/contact-url.ts index f285260c64..5620f99d00 100644 --- a/packages/client/ui-settings-account/src/client/contact-url.ts +++ b/packages/client/ui-settings-account/src/client/contact-url.ts @@ -1,15 +1,13 @@ /** Feishu questionnaire context follows the Platform Web ticket fields. */ import type { Config } from '../contact-config.ts' -import type { AccountProfile } from '@deepseek-ai/dsh-deepseek-account/types' /** * Build an external questionnaire URL without authentication credentials. * @param config - questionnaire destination and supported source option. - * @param context - currently available account and browser environment. + * @param context - currently available build and browser environment. * @returns questionnaire URL with hidden, optionally prefilled context fields. */ export function contactUrl(config: Config, context: { - uid: AccountProfile['id'] version: string | undefined locale: string width: number @@ -21,7 +19,7 @@ export function contactUrl(config: Config, context: { const width = Math.round(context.width * ratio) const height = Math.round(context.height * ratio) const fields = { - uid: context.uid, source: config.contactSource, app_version: context.version, + source: config.contactSource, app_version: context.version, os_version: undefined, device_brand: undefined, device_model: undefined, app_locale: context.locale, screen_resolution: width > 0 && height > 0 ? `${width}x${height}` : undefined, } diff --git a/packages/client/ui-settings-account/src/client/index.ts b/packages/client/ui-settings-account/src/client/index.ts index 3226eab0e6..3cc65e4668 100644 --- a/packages/client/ui-settings-account/src/client/index.ts +++ b/packages/client/ui-settings-account/src/client/index.ts @@ -84,9 +84,7 @@ export function apply(ctx: Context): void { ...nativePlatform === undefined ? {} : { platform: nativePlatform }, refresh, contactUs() { - const profile = snapshot.details?.profile const url = contactUrl(config, { - uid: profile?.status === 'ready' ? profile.value.id : null, version: process.env.DSH_CLIENT_VERSION, locale: ctx.locale.getSnapshot().active === 'zh' ? 'zh-CN' : 'en', width: window.screen.width, height: window.screen.height, pixelRatio: window.devicePixelRatio, diff --git a/packages/client/ui-settings-account/src/contact-config.ts b/packages/client/ui-settings-account/src/contact-config.ts index 65d4bb06a0..ee9cc3f3b6 100644 --- a/packages/client/ui-settings-account/src/contact-config.ts +++ b/packages/client/ui-settings-account/src/contact-config.ts @@ -10,7 +10,7 @@ export interface Config { } /** Validate public questionnaire options. */ export const Config: z, Config> = z.object({ - contactFormUrl: z.string().pattern(/^https:\/\/[^/\s]+\//).default('https://trtgsjkv6r.feishu.cn/share/base/form/shrcnhcHE4A6lQaQ3v0raCXmBAg'), + contactFormUrl: z.string().pattern(/^https:\/\/[^/\s]+\//).default('https://trtgsjkv6r.feishu.cn/share/base/form/shrcnlCoGElW7MQznGy9r3YYXcg'), contactSource: z.string().default(''), }) /** Bootstrap key containing no account credentials. */ diff --git a/packages/client/ui-settings-account/tests/apply.client.spec.ts b/packages/client/ui-settings-account/tests/apply.client.spec.ts index e1bf83f08e..348924b9ca 100644 --- a/packages/client/ui-settings-account/tests/apply.client.spec.ts +++ b/packages/client/ui-settings-account/tests/apply.client.spec.ts @@ -38,7 +38,9 @@ it('shares account actions across seats, publishes dialog ownership, and opens c actions.showLogin(false) expect(listener).toHaveBeenCalledTimes(2) actions.contactUs() - expect(new URL(String(open.mock.calls.at(-1)![0])).searchParams.has('prefill_uid')).toBe(false) + const signedOut = new URL(String(open.mock.calls.at(-1)![0])) + expect(signedOut.searchParams.has('prefill_uid')).toBe(false) + expect(signedOut.searchParams.has('hide_uid')).toBe(false) c.mock.remote.account.getProfile.mockResolvedValue(ok(profile)) c.mock.streams.push('account/watch', stored) await vi.waitFor(() => { expect(actions.hooks.account.getSnapshot().details?.profile).toEqual(profile) }) @@ -48,7 +50,8 @@ it('shares account actions across seats, publishes dialog ownership, and opens c vi.spyOn(c.ctx.locale, 'getSnapshot').mockReturnValue({ ...c.ctx.locale.getSnapshot(), active: 'zh' }) actions.contactUs() const support = new URL(String(open.mock.calls.at(-1)![0])) - expect(support.searchParams.get('prefill_uid')).toBe('account-user') + expect(support.searchParams.has('prefill_uid')).toBe(false) + expect(support.searchParams.has('hide_uid')).toBe(false) expect(support.searchParams.get('prefill_app_locale')).toBe('zh-CN') await c.unload(SELF) expect(c.ctx.slots.entries('settings.launcher')).toHaveLength(0) diff --git a/packages/client/ui-settings-account/tests/contact-url.client.spec.ts b/packages/client/ui-settings-account/tests/contact-url.client.spec.ts index 57d049e559..943c75cfe8 100644 --- a/packages/client/ui-settings-account/tests/contact-url.client.spec.ts +++ b/packages/client/ui-settings-account/tests/contact-url.client.spec.ts @@ -1,38 +1,39 @@ import { expect, it } from 'vitest' -import type { AccountUserId } from '@deepseek-ai/dsh-deepseek-account/types' import { Config } from '../src/contact-config.ts' import { contactUrl } from '../src/client/contact-url.ts' it('prefills available support context and hides all context fields', () => { const config = Config({ contactSource: 'app_harness' }) const url = new URL(contactUrl(config, { - uid: 'user&123' as AccountUserId, version: '1.2.3', locale: 'zh-CN', - width: 1512, height: 982, pixelRatio: 2, + version: '1.2.3', locale: 'zh-CN', width: 1512, height: 982, pixelRatio: 2, })) expect(url.origin).toBe('https://trtgsjkv6r.feishu.cn') expect(Object.fromEntries(url.searchParams)).toEqual({ - hide_uid: '1', prefill_uid: 'user&123', hide_source: '1', prefill_source: 'app_harness', - hide_app_version: '1', prefill_app_version: '1.2.3', hide_os_version: '1', + hide_source: '1', prefill_source: 'app_harness', hide_app_version: '1', prefill_app_version: '1.2.3', + hide_os_version: '1', hide_device_brand: '1', hide_device_model: '1', hide_app_locale: '1', prefill_app_locale: 'zh-CN', hide_screen_resolution: '1', prefill_screen_resolution: '3024x1964', }) + expect(url.searchParams.has('prefill_uid')).toBe(false) + expect(url.searchParams.has('hide_uid')).toBe(false) }) -it('opens a configured form without stale account context when signed out', () => { - const url = new URL(contactUrl(Config({ contactFormUrl: 'https://example.test/form/?prefill_uid=old&prefill_source=old' }), { - uid: null, version: undefined, locale: 'en', width: 0, height: 0, pixelRatio: 1, +it('opens a configured form without stale context when unavailable', () => { + const url = new URL(contactUrl(Config({ contactFormUrl: 'https://example.test/form/?prefill_app_version=old&prefill_source=old' }), { + version: undefined, locale: 'en', width: 0, height: 0, pixelRatio: 1, })) expect(url.origin).toBe('https://example.test') - expect(url.searchParams.has('prefill_uid')).toBe(false) + expect(url.searchParams.has('prefill_app_version')).toBe(false) expect(url.searchParams.has('prefill_source')).toBe(false) expect(url.searchParams.has('prefill_screen_resolution')).toBe(false) - expect(url.searchParams.get('hide_uid')).toBe('1') + expect(url.searchParams.get('hide_source')).toBe('1') + expect(url.searchParams.get('hide_app_version')).toBe('1') expect(() => Config({ contactFormUrl: 'javascript:alert(1)' })).toThrow() }) it.each([NaN, Infinity])('uses CSS pixel dimensions when device pixel ratio is %s', (pixelRatio) => { const url = new URL(contactUrl(Config({}), { - uid: null, version: undefined, locale: 'en', width: 800, height: 600, pixelRatio, + version: undefined, locale: 'en', width: 800, height: 600, pixelRatio, })) expect(url.searchParams.get('prefill_screen_resolution')).toBe('800x600') }) From 785a92ab03b0acfa215810d3cd3cf2290afdb8d7 Mon Sep 17 00:00:00 2001 From: lsdsjy <1356263+lsdsjy@users.noreply.github.com> Date: Tue, 22 Sep 2026 15:49:30 +0800 Subject: [PATCH 2/3] fix(client): rename the contact menu entry to Feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The account menu entry that opens the questionnaire is now labeled Feedback in English and 意见反馈 in Chinese. The menu action, contact form URL and its configuration options keep their existing names. Expected menu snapshots and the bilingual README record the new copy. --- packages/client/ui-settings-account/README.i18n.yaml | 4 ++-- packages/client/ui-settings-account/README.md | 2 +- packages/client/ui-settings-account/README.zh.md | 2 +- packages/client/ui-settings-account/src/client/locales.ts | 4 ++-- .../client/ui-settings-account/tests/expected/menu-en.txt | 2 +- .../client/ui-settings-account/tests/expected/menu-zh.txt | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/client/ui-settings-account/README.i18n.yaml b/packages/client/ui-settings-account/README.i18n.yaml index 67f94258b5..e971ba4553 100644 --- a/packages/client/ui-settings-account/README.i18n.yaml +++ b/packages/client/ui-settings-account/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-settings-account/README.md -README.md: 30d41fb49262619fd34f1bcd1abfec49d1248438 -README.zh.md: 1916bb2bb37704e5ecc22589620add82ce74780f +README.md: d06a13e877c13dd0a6695a73c44dcf10d2178c6c +README.zh.md: d010a0f6878b194df33f894b3b9b45610356dd45 diff --git a/packages/client/ui-settings-account/README.md b/packages/client/ui-settings-account/README.md index 30d41fb492..d06a13e877 100644 --- a/packages/client/ui-settings-account/README.md +++ b/packages/client/ui-settings-account/README.md @@ -28,7 +28,7 @@ Balances use Platform Web currency formatting: two decimal places and digit grou Desktop usage and top-up actions open an isolated native Platform view below a 48px return bar. Back destroys the view and preserves the Account settings page. Browser clients retain external links. Loading failures retain the return action and show a centered localized error with Retry. Retry reloads the same destination; renderer commands never receive the account token. -Contact us opens the Feishu questionnaire in the system browser on Desktop or a new browser tab on Web. It supplies the available build version, UI locale and physical screen resolution as prefill_* parameters, with hide_*=1 for every context field; the account UID, tokens and contact details are excluded. Configure contactFormUrl on the ui-settings-account plugin to select another HTTPS form. contactSource defaults to empty until the questionnaire supports a Harness source option; OS and device fields remain unfilled, matching the Web implementation. +The account menu's Feedback entry opens the Feishu questionnaire in the system browser on Desktop or a new browser tab on Web. It supplies the available build version, UI locale and physical screen resolution as prefill_* parameters, with hide_*=1 for every context field; the account UID, tokens and contact details are excluded. Configure contactFormUrl on the ui-settings-account plugin to select another HTTPS form. contactSource defaults to empty until the questionnaire supports a Harness source option; OS and device fields remain unfilled, matching the Web implementation. The sidebar account menu uses the shared Menu surface, backdrop blur, spacing, and row typography; feature styles only size its launcher. diff --git a/packages/client/ui-settings-account/README.zh.md b/packages/client/ui-settings-account/README.zh.md index 1916bb2bb3..d010a0f687 100644 --- a/packages/client/ui-settings-account/README.zh.md +++ b/packages/client/ui-settings-account/README.zh.md @@ -28,7 +28,7 @@ kind: "package-reference" Desktop 的用量和充值操作在 48px 返回栏下方打开隔离的原生 Platform 视图。返回操作销毁视图并保留 Account 设置页。浏览器客户端继续使用外链。加载失败时保留返回操作,居中显示本地化错误提示和“重试”按钮。重试重新加载同一目标页面;渲染进程命令不接收账号 token。 -“联系我们”在 Desktop 的系统浏览器或 Web 的新标签页打开飞书问卷。链接通过 prefill_* 参数填写已有的构建版本、界面语言和屏幕物理分辨率,并为所有上下文字段设置 hide_*=1;不传账号 UID、token 或联系方式。可在 ui-settings-account 插件配置 contactFormUrl,切换到另一个 HTTPS 问卷。问卷支持 Harness 来源选项前,contactSource 默认为空;OS 和设备字段沿用 Web 实现,保持未填写。 +账号菜单的“意见反馈”入口在 Desktop 的系统浏览器或 Web 的新标签页打开飞书问卷。链接通过 prefill_* 参数填写已有的构建版本、界面语言和屏幕物理分辨率,并为所有上下文字段设置 hide_*=1;不传账号 UID、token 或联系方式。可在 ui-settings-account 插件配置 contactFormUrl,切换到另一个 HTTPS 问卷。问卷支持 Harness 来源选项前,contactSource 默认为空;OS 和设备字段沿用 Web 实现,保持未填写。 侧边栏账号菜单使用公共 Menu 的表面、背景模糊、间距和菜单项排版;功能样式仅设置入口布局。 diff --git a/packages/client/ui-settings-account/src/client/locales.ts b/packages/client/ui-settings-account/src/client/locales.ts index 58ca7fb7ba..2e4b40474d 100644 --- a/packages/client/ui-settings-account/src/client/locales.ts +++ b/packages/client/ui-settings-account/src/client/locales.ts @@ -8,7 +8,7 @@ export const en = { failureTitle: 'Could not sign in', platformFailed: 'Could not complete the operation. Try again.', platformRetry: 'Retry', loading: 'Loading…', backToHarness: 'Back to DeepSeek Harness', - settings: 'Settings', contactUs: 'Contact us', menu: 'Account menu', + settings: 'Settings', contactUs: 'Feedback', menu: 'Account menu', nav: 'Account', signedIn: 'Signed in to DeepSeek', signedOut: 'Not signed in', signIn: 'Sign in', signOut: 'Sign out', cancel: 'Cancel', open: 'Open browser', initializing: 'Starting sign in…', waiting: 'Continue in your browser', @@ -33,7 +33,7 @@ export const zh: Record = { failureTitle: '登录失败', platformFailed: '操作未完成,请重试', platformRetry: '重试', loading: '加载中…', backToHarness: '返回 DeepSeek Harness', - settings: '设置', contactUs: '联系我们', menu: '账号菜单', + settings: '设置', contactUs: '意见反馈', menu: '账号菜单', nav: '账号与余额', signedIn: '已登录 DeepSeek', signedOut: '尚未登录', signIn: '登录', signOut: '退出登录', cancel: '取消', open: '打开浏览器', initializing: '正在发起登录…', waiting: '请在浏览器中继续', diff --git a/packages/client/ui-settings-account/tests/expected/menu-en.txt b/packages/client/ui-settings-account/tests/expected/menu-en.txt index dd5eac1f91..1addd6d26a 100644 --- a/packages/client/ui-settings-account/tests/expected/menu-en.txt +++ b/packages/client/ui-settings-account/tests/expected/menu-en.txt @@ -1 +1 @@ -SettingsContact usSign out +SettingsFeedbackSign out diff --git a/packages/client/ui-settings-account/tests/expected/menu-zh.txt b/packages/client/ui-settings-account/tests/expected/menu-zh.txt index a96ac28fe7..be4f55f3b6 100644 --- a/packages/client/ui-settings-account/tests/expected/menu-zh.txt +++ b/packages/client/ui-settings-account/tests/expected/menu-zh.txt @@ -1 +1 @@ -设置联系我们退出登录 +设置意见反馈退出登录 From 4777947b6c00810c7e102b9efbd64a5994508ff6 Mon Sep 17 00:00:00 2001 From: lsdsjy <1356263+lsdsjy@users.noreply.github.com> Date: Tue, 22 Sep 2026 16:16:34 +0800 Subject: [PATCH 3/3] fix(client): keep account UID fields out of questionnaire URLs The Contact us action already stopped prefilling the signed-in UID, but a configured contact form URL could still carry its own prefill_uid or hide_uid. contactUrl now drops both query parameters unconditionally, with regression coverage that starts from a form URL containing them. The contact URL test also pins the shipped default form path, and the injected contactUs documentation and the AccountProfile summary no longer describe a support UID that is no longer sent. --- .../client/ui-settings-account/src/client/AccountSection.tsx | 2 +- .../client/ui-settings-account/src/client/contact-url.ts | 2 ++ .../ui-settings-account/tests/contact-url.client.spec.ts | 5 ++++- packages/credentials/deepseek-account/src/types.ts | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/client/ui-settings-account/src/client/AccountSection.tsx b/packages/client/ui-settings-account/src/client/AccountSection.tsx index d5e4f5d82a..1b0d344bd0 100644 --- a/packages/client/ui-settings-account/src/client/AccountSection.tsx +++ b/packages/client/ui-settings-account/src/client/AccountSection.tsx @@ -40,7 +40,7 @@ export interface AccountSectionInjected { } /** @returns after account details are refreshed; concurrent refreshes share a request. */ refresh: () => Promise - /** Open the external support questionnaire with the current account and environment. */ + /** Open the external support questionnaire with the current build and browser environment. */ contactUs: () => void /** Open or dismiss the login dialog. */ showLogin: (visible: boolean) => void diff --git a/packages/client/ui-settings-account/src/client/contact-url.ts b/packages/client/ui-settings-account/src/client/contact-url.ts index 5620f99d00..524a441139 100644 --- a/packages/client/ui-settings-account/src/client/contact-url.ts +++ b/packages/client/ui-settings-account/src/client/contact-url.ts @@ -28,5 +28,7 @@ export function contactUrl(config: Config, context: { url.searchParams.delete(`prefill_${name}`) if (value) url.searchParams.set(`prefill_${name}`, value) } + url.searchParams.delete('prefill_uid') + url.searchParams.delete('hide_uid') return url.href } diff --git a/packages/client/ui-settings-account/tests/contact-url.client.spec.ts b/packages/client/ui-settings-account/tests/contact-url.client.spec.ts index 943c75cfe8..3e00ee99ba 100644 --- a/packages/client/ui-settings-account/tests/contact-url.client.spec.ts +++ b/packages/client/ui-settings-account/tests/contact-url.client.spec.ts @@ -8,6 +8,7 @@ it('prefills available support context and hides all context fields', () => { version: '1.2.3', locale: 'zh-CN', width: 1512, height: 982, pixelRatio: 2, })) expect(url.origin).toBe('https://trtgsjkv6r.feishu.cn') + expect(url.pathname).toBe('/share/base/form/shrcnlCoGElW7MQznGy9r3YYXcg') expect(Object.fromEntries(url.searchParams)).toEqual({ hide_source: '1', prefill_source: 'app_harness', hide_app_version: '1', prefill_app_version: '1.2.3', hide_os_version: '1', @@ -19,10 +20,12 @@ it('prefills available support context and hides all context fields', () => { }) it('opens a configured form without stale context when unavailable', () => { - const url = new URL(contactUrl(Config({ contactFormUrl: 'https://example.test/form/?prefill_app_version=old&prefill_source=old' }), { + const url = new URL(contactUrl(Config({ contactFormUrl: 'https://example.test/form/?prefill_uid=old&hide_uid=1&prefill_app_version=old&prefill_source=old' }), { version: undefined, locale: 'en', width: 0, height: 0, pixelRatio: 1, })) expect(url.origin).toBe('https://example.test') + expect(url.searchParams.has('prefill_uid')).toBe(false) + expect(url.searchParams.has('hide_uid')).toBe(false) expect(url.searchParams.has('prefill_app_version')).toBe(false) expect(url.searchParams.has('prefill_source')).toBe(false) expect(url.searchParams.has('prefill_screen_resolution')).toBe(false) diff --git a/packages/credentials/deepseek-account/src/types.ts b/packages/credentials/deepseek-account/src/types.ts index f59c959567..7245ba1418 100644 --- a/packages/credentials/deepseek-account/src/types.ts +++ b/packages/credentials/deepseek-account/src/types.ts @@ -27,7 +27,7 @@ export interface AccountView { /** Platform account identifier supplied by the current-user endpoint. */ export type AccountUserId = Branded<'AccountUserId'> -/** Display identity and support UID; contacts retain Platform masking. */ +/** Display identity; contacts retain Platform masking. */ export interface AccountProfile { readonly id: AccountUserId | null readonly name: string | null