Repository navigation
fix(app-shell): the impersonation banner names the administrator by name or email, never by a raw user id - #29272
Conversation
…ever the raw user id The banner read the administrator from session.impersonatedBy, a sys_user id, and printed it. It now reads that one sys_user row (as the session the console holds) and names it by name, else email; a refused, missing or failed read says "an administrator". The remediation overlay, which shares the exit hook, issues no read. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jTfuF6dXc7H9Ajpbej
…ute in the banner harness Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jTfuF6dXc7H9Ajpbej
…esponse body Measured on a live showcase: the route answers the spec body unwrapped. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jTfuF6dXc7H9Ajpbej
|
domain:ui#5 · zhuangjianguo · session_01QsR2jQjvWkZ7is6GXbC6DB Contract reviewServed-tier: Face: the ① Derived judgments
② Semver level
③ Boundary flagsNone raised. A real browser run was MEASURED by the dev on the showcase, both legs, with screenshots in Implemented-by: VERDICT: PASS |
|
domain:ui#5 · zhuangjianguo · session_01QsR2jQjvWkZ7is6GXbC6DB 席位核对 — ACCEPT ·
|
Requested by Steedos · project thread
Fixes #29161
Clause-②: yes (widening)
Metadata-protocol: none
维护者速读
ui/packages/app-shell/src/layout/ImpersonationBanner.tsx(useAdministratorName的一次读取与三种结果);ui/packages/app-shell/src/layout/__tests__/ImpersonationBanner.test.tsx;ui/packages/i18n/src/locales/en.ts(新键startedByUnnamed)。What changes
ImpersonationBannernames the administrator. The session carries the administrator only assession.impersonatedBy(asys_userid). The banner now reads that one row,GET /api/v1/data/sys_user/ID, throughcreateAuthenticatedFetch(the session the console holds, which is the impersonated user's), parses the body with the spec'sGetDataResponseSchema, and names the administrator by the first non-empty of the person display columnsapproverIdentityalready uses forsys_user(full name, name, display name, email).GetDataResponseshape, or a row with neither name nor email shows "Started by an administrator." The raw id is never rendered, and the sentence is held back until the read answers, so it never flips from an id to a name.ConsoleShell, aboveAdapterProvider, souseAdapter()has nothing there. The/api/v1lane is the one the banner's exit (useImpersonationExit) andstorageUsageEndpointalready use from the same shell level.RemediationOverlayis unchanged. The read lives in the banner, not in the shareduseImpersonationExit, so the overlay (which names nobody) issues no read.impersonation.banner.startedByUnnamedin all ten@object-ui/i18npacks, henceClause-②: yes (widening)(the claim was amended for it).Tests
ImpersonationBanner.test.tsx(13 cases, on the realAuthProvider+ real locale packs):usr_adminappears nowhere; the read goes to/api/v1/data/sys_user/usr_adminwith the impersonated bearer;admin: administrator.namemutated toadmin: impersonatedBy(pass the id back) throughscripts/ablation-replace.mjs: 2 cases red ("names BOTH parties", "names the administrator by email"), 11 green; restored, blob equal to HEAD andgit diff HEADempty.cb02bf18(after mergingmain), underscripts/pm/os-verify-lock.sh:pnpm --dir ui exec vitest run packages/app-shell/src/layout/__tests__/ImpersonationBanner.test.tsx packages/app-shell/src/console/__tests__/RemediationOverlay.impersonation-13208.test.tsx: 2 files, 19 tests passed (the overlay's 6 unchanged).pnpm --dir ui exec vitest run packages/i18n/: 95 files passed, 1443 tests passed, 13 skipped (run before the merge; the merge moved only the Studio namespace in i18n).turbo run type-check --filter=@object-ui/app-shell --filter=@object-ui/i18n: 66 tasks, exit 0 (bothtscprograms, source and tests).Acceptance notes
GET /data/sys_user/IDas the spec'sGetDataResponsebody with nosuccess/dataenvelope (measured live, below); the banner reads that shape only./api/v1/dataprefix, as the exit uses/api/v1/auth. A deployment that movedcrud.dataPrefixgets a 404 there and the banner says "an administrator", never the id.Verification
Live showcase (
pnpm dev -- --fresh, framework at this branch before the main merge, Console Vite dev proxied to it), adminadmin@objectos.ai, a new user "RT Dave" created withadmin/create-userand impersonated withadmin/impersonate-user:get-sessionreportsimpersonatedBy= the admin's id;GET /api/v1/data/sys_user/ADMIN_IDas Dave answers 200{"object":"sys_user","id":…,"record":{…"name":"Dev Admin","email":"admin@objectos.ai"…}}; the banner reads "You are impersonating RT Dave — every action is recorded as them. Started by administrator Dev Admin."organization/remove-member), re-impersonated: the same GET answers 404RECORD_NOT_FOUND(thesys_userrow scope is own row plus organization members),GET /data/sys_userlists only Dave's own row; the banner reads "… Started by an administrator." with no id.Derived gates (34), at head cb02bf1
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 34 commands; every one exited 0, and--ranreconciles 34 derived, 34 run, 0 NOT-MEASURED. Among themnode scripts/check-sdui-manifest.mjs(and its--self-test),check-changeset-no-major,check-adr-0087-registration,check-closing-keyword-parity(run against this body),check:nul-bytes,check:cross-package-test-inputs,check:published-files,check:type-check-debt(locked) andpnpm --dir ui exec vitest run scripts/(169 files passed, 2 skipped). The firstvitest run scripts/was red incheck-readme-exports.test.tsonly, on@object-ui/mobileREADME imports that themainmerge added while the localmobiledist predated it; after rebuilding@object-ui/mobilethe full suite reran green.Generated by Claude Code