Repository navigation
fix(platform-objects): credential action params declare type password, so the dialog masks what is typed - #24867
Conversation
… so the dialog masks them Claude-Session: https://claude.ai/code/session_01G3YZBh5FVysqzzALckNTWy Co-authored-by: Claude <noreply@anthropic.com>
…les about a password Claude-Session: https://claude.ai/code/session_01G3YZBh5FVysqzzALckNTWy Co-authored-by: Claude <noreply@anthropic.com>
…on and param Claude-Session: https://claude.ai/code/session_01G3YZBh5FVysqzzALckNTWy Co-authored-by: Claude <noreply@anthropic.com>
…ssword-param-type
📓 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 62a4fc353cdee0a46055907dd68941ee551c374a && git checkout 62a4fc353cdee0a46055907dd68941ee551c374a
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 81120caac889335467b6ecc6f17fcab57c46e6f5 d46ae39da0dc1392814088cfc412986ac453d528 && git checkout -B drift-repro 81120caac889335467b6ecc6f17fcab57c46e6f5 && git merge --no-ff d46ae39da0dc1392814088cfc412986ac453d528
node scripts/docs-audit/affected-docs.mjs --json 81120caac889335467b6ecc6f17fcab57c46e6f5
|
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 #24758. 5 files, +86/−12. Not governed: check-governed-merges matched 0 of 5 paths. |
| Scope | Twelve credential action params on the identity objects declare type: 'password' instead of text, so the console's action dialog masks what is typed: the card's create_user#password and set_user_password#newPassword, the self-service password and two-factor params on sys_user and sys_two_factor, and register_sso_provider#clientSecret. Labels, names, required and the posted body are unchanged. |
| Seat's own read | Each hunk is the one type token. The posted value and every endpoint are untouched. The sweep pin's positive control holds the roster exact. git merge-tree is clean against main and against sibling PR #24870. |
| Review | TIER_DEFAULT, in-seat. Record 6291117267 is PASS on this head. |
| Declaration | One changeset, @objectstack/platform-objects patch, Clause-②: no (…) at a line start, as on the claim and the PR body. No export, key or field type is added. |
| Cross-lane | None: all three files are packages/platform-objects, this lane's. No checklist or bundle file. No objection on the card or the seat posts. |
| Gates | Dev at d46ae39da: 66 derived, 66 run, all exit 0. platform-objects 1212 passed, plugin-auth 3260 passed, core test:repo 82 passed. Ablation: two legs, each red, restored to HEAD. |
| CI | At this read on d46ae39da0: ci-failure GREEN, all 41 check-runs completed, none failed. |
Disposition:
open_questions: both taken as the dev settled them (record ③): all twelve params land here;passwordforclientSecret.deviations: all accepted (record ③). The surface widened to two sibling identity files of the same defect class. The dependent suites were narrowed to the endpoints' consumer.out_of_scope_findings: none.
Landing: ordinary queue (pr_ready + automerge_enable through the relay). Fixes #24758 then closes the card.
Generated by Claude Code
Fixes #24758
Clause-②: no (an input's presentation: the param still accepts the same string, and no accept set or served shape moves)
What changed
Every credential param on the identity objects' actions now declares
type: 'password'instead oftype: 'text', so the console's action dialog draws a masked input and the typed value is no longer readable on screen or in screenshots. Labels, names,requiredand the posted body are unchanged.sys_usercreate_userpassword(the card)sys_userset_user_passwordnewPassword(the card)sys_userchange_my_passwordcurrentPassword,newPasswordsys_userdelete_my_account,enable_two_factor,disable_two_factor,generate_backup_codespasswordsys_two_factorenable_two_factor,disable_two_factor,regenerate_backup_codespasswordsys_sso_providerregister_sso_providerclientSecretFiles:
packages/platform-objects/src/identity/sys-user.object.ts(the claim's surface),sys-two-factor.object.tsandsys-sso-provider.object.ts(outside the claim's listed surface, see below), the pins inpackages/platform-objects/src/platform-objects.test.ts, and apatchchangeset for@objectstack/platform-objects.Read before the edit
.objectui-sha616df6598b42).ActionParamDialogbuilds every param throughparamToField(), whose widget key isresolveParamWidgetType(param.type)→resolveFormWidgetType.passwordis a key offieldWidgetLoaderByKeyin@object-ui/fields, loadingwidgets/PasswordField.tsx, which renders its input with typepassword(with a show/hide toggle) and posts the string throughonChangeexactly as the text widget does. So apasswordparam is masked in the console today; no objectui change is needed.type:resolvePasswordinplugin-auth'sadmin-user-endpoints.tsreadsbody.password/body.newPasswordas strings;MASKED_ON_READ_FIELD_TYPES/isMaskedOnReadFieldTypeand the generic-object plaintext warning inobject.zod.tsjudge object FIELDS only, never action params.ActionParamSchema.typeisFieldType, which admitspassword. What the server accepts is unchanged.git grep -n "assword" -- 'packages/platform-objects/src/**/*.object.ts'): the eightsys_userparams and threesys_two_factorparams in the table. A second sweep for credential-named params (password,secret,token) declaredtype: 'text'acrosspackages/**andexamples/**found one more,sys_sso_provider.register_sso_provider#clientSecret.Scope notes
sys-two-factor.object.tsis outside the claim'sFile surface:; the dispatch names "any other password-like param on the platform objects declaredtype: 'text'" as in scope, so its three params land here.sys_sso_provider'sclientSecretis landed as a bounded in-place fix: the same defect class (a credential typed into an action dialog shown in clear), the same one-token mechanical change pinned by the same test, no open PR or claim on that file, and no new gate family.pnpm check:i18nis green after the build.Pins
credential action params declare 'password', so the dialog masks what is typedinplatform-objects.test.ts: a roster row per param above assertingtype === 'password', plus a sweep over every object exported from./identity/index.jsthat fails on any credential-named param (/password|secret/i, boolean toggles such asmustChangePasswordexcepted) not declaredpassword; its positive control asserts the sweep reaches exactly the rostered params.qa/,docs/qa/platform-checklist/andcontent/docs/. No existing pin asserts these params' type, so no pin moves.Verification record
Base
abd5acdaf, mergedorigin/main9a06f0be0before opening; headd46ae39da.pnpm --filter @objectstack/platform-objects typecheck: exit 0 (before and after the merge).pnpm --filter @objectstack/platform-objects test(full suite): exit 0, 79 files / 1212 tests passed (after the merge).pnpm --filter @objectstack/core test:repo: exit 0, 6 files / 82 tests.pnpm --filter @objectstack/plugin-auth test(the endpoint consumer): exit 0, 170 files, 3260 passed / 10 skipped.turbo run buildover the workspace after the merge, 76/76 tasks.scripts/ablation-replace.mjs(fix committed first; the test importssrc, no dist): revertingcreate_user#passwordtotext→ 2 failed (roster row + sweep), restored to HEAD blob7abf5fe3a3fb; revertingset_user_password#newPassword→ 2 failed (SysUser.set_user_password#newPassword declares 'password'+ sweep), restored,git diff HEADempty.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 66 commands, each run with its exit code captured before any pipe; all exit 0.pnpm check:i18n,pnpm check:dual-build-cjs-loadsandpnpm check:lean-entry-closurefirst exited 3 (PREREQUISITE NOT MET, no build) and were re-run green after the build.--ranreconciliation: 66 derived, 66 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero: all 66 carry an exit code). After the merge, the changeset, ADR-0087, keyed-text-bounds, tenancy-census, nul-bytes and type-check coverage/debt families were re-run ond46ae39da: all exit 0.Acceptance notes
@objectstack/setupand@objectstack/accountdeclare notestscript; their filtered runs ran nothing.Generated by Claude Code