Repository navigation
fix(platform-objects): Rotate Client Secret result dialog states the immediate cut-off, not a grace period - #24870
Conversation
…te cut-off Claude-Session: https://claude.ai/code/session_01MrvwG9BMeMc4oCSG9FsV95 Co-authored-by: Claude <noreply@anthropic.com>
…ce and every locale Claude-Session: https://claude.ai/code/session_01MrvwG9BMeMc4oCSG9FsV95 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MrvwG9BMeMc4oCSG9FsV95 Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 3 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 49e6550ad08256b76573ea0bb6e97d912a297dbc && git checkout 49e6550ad08256b76573ea0bb6e97d912a297dbc
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 6b9e6df909dade0e2e2f2e4ee90de22fefff2a91 c41eb194965fe4833bcf55aded03474e5ed79bf3 && git checkout -B drift-repro 6b9e6df909dade0e2e2f2e4ee90de22fefff2a91 && git merge --no-ff c41eb194965fe4833bcf55aded03474e5ed79bf3
node scripts/docs-audit/affected-docs.mjs --json 6b9e6df909dade0e2e2f2e4ee90de22fefff2a91
|
Contract reviewServed-tier: ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
席位核对 ·
|
| Item | Reading |
|---|---|
| Shape | Draft PR → main. The body opens Fixes #24774. 7 files, +101/−5. Not governed: check-governed-merges matched 0 of 7 paths. |
| Scope | Rotate Client Secret's result dialog no longer promises a grace period. It now says the previous secret has already stopped working, as the confirmation already said. The four locales agree. The confirmation, the dialog's title, its acknowledgement and its secret field are unchanged. |
| Seat's own read | Read in @better-auth/oauth-provider 1.7.3, the pinned version: rotateClientSecretEndpoint overwrites oauthClient.clientSecret in one update and keeps no previous secret, and validateClientCredentials checks only that column. So the cut-off is immediate. git merge-tree is clean against main and against sibling PR #24867. |
| Review | TIER_DEFAULT, in-seat. Record 6291126289 is PASS on this head. |
| Declaration | One changeset, @objectstack/platform-objects patch, Clause-②: no (text only: …) at a line start, as on the claim and the PR body. No behaviour, accept set or served shape moves. |
| Cross-lane | None: packages/platform-objects is this lane's. plugin-auth was read only. No objection on the card or the seat posts. |
| Gates | Dev at c41eb1949: 66 derived, 66 run, all exit 0. platform-objects 1203 passed, core test:repo 82 passed, and the runtime and cli consumer tests 63 and 34 passed. Ablation: source and zh-CN legs, each red, restored to HEAD. |
| CI | At this read on c41eb19496: ci-failure GREEN, all 41 check-runs completed, none failed. |
Disposition:
open_questions: A, copy follows the handler (record ③). A grace window would be a new auth capability with no pull.deviations: all accepted (record ③). The three translated values were edited by hand because the extractor keeps translated values in merge mode. The dependent suites were narrowed to the action's consumers. The pin asserts copy, and here the copy is the defect.out_of_scope_findings: the illustrativetargetincontent/docs/protocol/objectui/actions.mdxmeets no filing gate; it is noted in the PR.- Siblings: this is the only one of the three sibling PRs that touches the translation bundles, so nothing needs re-deriving.
Landing: ordinary queue (pr_ready + automerge_enable through the relay). Fixes #24774 then closes the card.
Generated by Claude Code
Fixes #24774
Clause-②: no (text only: no accept set, served shape or behaviour moves)
Dispatched by the
domain:engineseat 1 PM (session_01JtSQQ3EWsbNPzyYMug1tXy, claim 6289452299). Developer session:session_01MrvwG9BMeMc4oCSG9FsV95.What rotation does to the previous secret (read first)
POST /api/v1/auth/oauth2/client/rotate-secretis better-auth's own route.plugin-authonly lists it inauth-route-ledger.ts, and nothing in this repository wraps it.@better-auth/oauth-provider1.7.3,rotateClientSecretEndpoint(dist/authorize-9whjxVLJ.mjs) generates a new secret and runs oneadapter.updatethat overwrites the client's singleclientSecretcolumn. No previous secret is stored anywhere.validateClientCredentials(dist/utils-oOcdCCVw.mjs), checks a presented secret against that one storedclient.clientSecretthroughverifyStoredClientSecret. There is no second value to match.content/docs/protocol/objectui/actions.mdxalready says "The current secret stops working immediately". So the confirmation was true and the result dialog was false. The behaviour itself is not in question here.Change
sys-oauth-application.object.ts,rotate_client_secret:description(the confirmation) is unchanged. It was already true.resultDialog.descriptionnow reads "Save the new secret now — it is shown only once. The previous secret has already stopped working: update every integration with the new secret." The shown-once sentence, the title, the acknowledgement and theclient_secretfield are kept.en.objects.generated.tswas regenerated withpnpm i18n:extract, and only that one line moved.zh-CN,ja-JPandes-ESall carried a translated grace-period sentence. These are hand-written translated values, not byte copies, so they have no source-hash entry. The extractor keeps them in merge mode, and the staleness rule ("a path with no entry is LEGACY-TRUSTED and never reported stale") would never flag them. So I re-translated the value by hand in each locale. No keys were added or dropped.check:i18nis in sync.Pins
packages/platform-objects/src/identity/rotate-client-secret-copy.test.ts:enbundle mirrors the source;宽限,猶予,graciaand similar words), and each translated result dialog is a real translation, not the English text.scripts/ablation-replace.mjs. Each mutation was confirmed on disk, and each restore was proven by blob hash against HEAD. There is no dist leg: the test importssrcrelatively.resultDialog.description(blobd5ffc56c6b52to4f08d6f86141). 2 failed, 2 passed (4). The source-agreement test and theen-mirror test went red. Restored tod5ffc56c6b52.65c34bca849dto0b3f3e584462). 1 failed, 3 passed (4):zh-CN resultDialog.description promises a grace period. Restored to65c34bca849d.qa/,docs/qa/platform-checklist/andcontent/docs/for the old and new strings and forrotate_client_secret.action-confirm-one-dialog.test.tspins the unchanged confirmation ("stop working immediately", "shown only once"). It stays green and does not move.docs/qa/platform-checklist/**item names this action.Verification record
Base
abd5acdaf7, merged withorigin/main9a06f0be0before opening (the merge touched nothing inplatform-objects). All results are on headc41eb1949.pnpm --filter @objectstack/platform-objects typechecktsconfig.test.json's program (--listFiles: 1 hit).pnpm --filter @objectstack/platform-objects test(full suite)pnpm --filter @objectstack/core test:repopnpm exec turbo run build --concurrency=2(whole workspace, docs excluded, after the merge)vitest runofruntime'ssrc/action-execution-destructive.test.ts(this action's consumer test), against the rebuiltplatform-objectsdistvitest runofcli'stest/platform-page-i18n-parity.test.tsandtest/i18n-extract-action-description.test.tsdispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 66 derived commands, each run with its exit code captured before any pipe--ran(each line recorded asCOMMAND :: exit CODE): "66 derived famil(ies) accounted for — 66 run, 0 NOT-MEASURED (a DERIVED zero — all 66 recorded an exit code and none of them is 3)"On the first run,
check:i18nandcheck:dual-build-cjs-loadsexited 3 (PREREQUISITE NOT MET: nodist/). I built the whole workspace, and both then exited 0.Siblings
This PR regenerates one line of the
platform-objectsenbundle and changes one value in each of the three translated bundles. Whichever of #24758, #24765 and this one lands second re-derives the bundles withscripts/pm/os-regen-merge.sh.Acceptance notes
content/docs/protocol/objectui/actions.mdx("Create via API with secret reveal") givestarget: /api/v1/auth/sys-oauth-application/rotate-secret. That is not the route the shipped action calls (/api/v1/auth/oauth2/client/rotate-secret). It is an illustrative docs example, and its own copy already says the cut-off is immediate. Noted, not filed.🤖 Generated with Claude Code
https://claude.ai/code/session_01MrvwG9BMeMc4oCSG9FsV95
Generated by Claude Code