Repository navigation
feat(console): ask for the installer's OAuth client on Connect for a clientSource installer connector - #29496
Merged
Merged
Conversation
An oauth2 connector instance declaring clientSource: 'installer' now opens a
client form on Connect / Reconnect: client id and a masked, write-only client
secret. The begin POST carries { clientId, clientSecret }; a reconnect shows
the stored client id and whether a secret is kept, prefills the id and sends
the client again. Every other instance connects with no form, as before.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsR2jQhfprmgNtfhzNURJ6
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jQhfprmgNtfhzNURJ6
Contributor
Author
|
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m 席位核对 · ACCEPT · 2026-11-02T16:49ZHead-sha:
|
This was referenced Nov 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Steedos · project thread
Part of #28869
Clause-②: yes
Metadata-protocol: none
PR 1 of 2 on the card, per the seat's claim amendment (6581522588, option B): items 1, 3, 4 and 5. Item 2, the redirect URI with a copy button, is PR 2 on this card once the server half #29463 lands, because no answer the Console reads carries the redirect URI today (stop report 6581473243).
维护者速读
clientSource: 'installer'的 OAuth 连接器,在 设置 → 集成 → 连接器连接 页点「连接」或「重新连接」时,先弹出表单让管理员填写在供应商处登记的 Client ID 和 Client secret,再打开供应商登录窗口;连接请求体带{ clientId, clientSecret }。secret 输入框为密码框,每次打开都是空的,提交即清空,页面上永不显示。已连接的行显示「OAuth client 某 ID, secret stored」。其他连接器照旧,无表单。clientIdis fixed by the package and the redirect URI is per deployment #28702 裁决 B 的界面半边;服务端 feat(automation): an oauth2 connector with clientSource: 'installer' connects with the administrator's OAuth client #29097 已合并,此前控制台连接这类实例会得到 400。ui/packages/app-shell/src/views/setup/ConnectorConnectionsPage.tsx的startConnect/submitClient(提交前清空 secret 那一行);connectorConnections.ts的beginConnection请求体;readConnectableInstances的clientSource判定。pnpm --dir ui exec vitest run packages/app-shell/src/views/setup/ConnectorConnectionsPage.test.tsx,应看到 17 条全过(新增 6 条在 an installer-supplied OAuth client 组)。新增语言键(
connectorConnections下 12 个,十种语言全部补齐):clientKeptWithSecret、clientKept、clientTitle、clientIntro、clientStored、clientStoredSecret、clientStoredNoSecret、clientResend、clientId、clientSecret、clientSecretHint、clientContinue。What changes
connectorConnections.ts:readConnectableInstancesmarks an instance whose declaration (GET /meta/connector) saysauth.clientSource: 'installer'.beginConnection(name, client?)sends{ clientId, clientSecret? }as a JSON body for such an instance and no body otherwise, exactly as before.ConnectorConnectionsPage.tsx: Connect / Reconnect on an installer-client instance opens a form (client ID; masked client secret withautocomplete=new-password) before any window opens or anything is sent. Continue opens the sign-in window on that click and begins with the client. The secret is cleared from the form state before the begin is awaited; a refused begin keeps the form open with the server's words and an empty secret. A connected row shows the kept client fromclient { clientId, hasSecret }on the status. Reconnect shows the stored client ID and whether a secret is kept, prefills the ID, leaves the secret empty and sends the client again: today's server refuses a client-less begin of such an instance on every begin, reconnect included (installerClientOfBegin). The client-less reconnect that reuses the stored client is ask 2 of connector connection state: answer the derived OAuth redirect URI so the Console can show it before an installer registers a client #29463; PR 2 switches to it. Every other instance (a declared client, an MCP dynamically registered client) connects at once with no form and no body.@object-ui/i18n: the twelve keys above in all ten locales (the all-locales parity suite requires every pack, so the card's four became ten)..changeset/28869-installer-oauth-client-form.md(@object-ui/app-shell,@object-ui/i18n: patch).Tests
New
describe('an installer-supplied OAuth client')inConnectorConnectionsPage.test.tsx, six cases: the form appears before any window or POST and the begin carries{ clientId, clientSecret }(id trimmed); a public client sends only{ clientId }; a refused begin keeps the form with the server's words and an empty secret; a reconnect shows the stored client, prefills the id, starts with an empty secret and sends the client again (today's server behaviour, pinned); Cancel sends nothing and the next opening has an empty secret; no other instance shows the form and its begin has no body. Every case that types the secret asserts it is absent fromdocument.body.innerHTMLafterwards.Acceptance notes
all-locales-key-parityholds every pack to the same key set.app-crm; the token leg authenticated with HTTP Basic as the installer's client, as the server half intends.Verification
Page suite, ablations (head bc8ea24, re-run on merge 4a4fe17)
pnpm exec vitest run packages/app-shell/src/views/setup/ConnectorConnectionsPage.test.tsx(fromui/, under os-verify-lock): 17 passed (11 existing + 6 new). On merge head 4a4fe17 withpackages/i18n/: Test Files 96 passed, Tests 1460 passed, 13 skipped.scripts/ablation-replace.mjs, restored blob == HEAD,git diff HEADempty): the installer gate instartConnectdropped, so every instance gets the form: 6 failed / 11 passed, the "no other instance shows the form" pin among them.readConnectableInstancesnever marksclientSource: 'installer': 5 failed / 12 passed (every installer case).@object-ui/*to source, so no rebuild leg was owed.Packages and gates (head bc8ea24)
pnpm exec vitest run packages/i18n/(under the lock): Test Files 95 passed, Tests 1443 passed, 13 skipped.turbo run type-check --filter=@object-ui/app-shell --filter=@object-ui/i18n: 66 tasks successful, VERDICT command-exit 0.pnpm --dir ui exec vitest run scripts/: Test Files 169 passed, 2 skipped; Tests 4921 passed.node scripts/check-sdui-manifest.mjs: exit 0 (no registry change).dispatch-gates --commands: 34 families, every one exit 0;--ran: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN.Live run (app-crm, Vite source Console)
objectstack dev --seed-admin --freshon app-crm withOS_BASE_URLset to the Console origin, the Vite Console proxying to it, a local stub for the vendor's authorize/token endpoints, and an installer connector saved throughPUT /meta/connector/vendor_docs(clientSource: 'installer', the dogfood fixture's shape). In Playwright: Connect opened the client form; Continue sentPOST .../vendor_docs/connectionwith body keysclientId,clientSecret; the stub saw the authorize request with that client id and the token request authenticated as that client; the page showed Connected and "OAuth client live-installer-client, secret stored"; the status read answeredclient: { source: 'installer', clientId: 'live-installer-client', hasSecret: true }. Reconnect opened the form with the id prefilled and the secret empty. The typed secret was absent from the page's HTML after the connect and in the reconnect form. Screenshots of the Connect step, the connected row and the Reconnect step were handed to the seat.Generated by Claude Code