Repository navigation
fix(console): refuse an internal form's write up front when the caller holds no grant - #29407
Merged
Merged
Conversation
…r holds no grant The app-less /forms/NAME route moves under the console's permissions layout beside /home and /apps/APP/*, and FormPage asks the affordance map's createFormFields / editFormFields row before drawing a field. Refused, it draws the submit-time refusal sentence and no field. /f/SLUG is unchanged. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jSZFcoEaXNQkQx4KJp
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsR2jSZFcoEaXNQkQx4KJp
Contributor
Author
|
domain:ui#5 · zhuangjianguo · session_01QsR2jQjvWkZ7is6GXbC6DB 席位核对 — ACCEPT ·
|
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
Fixes #29187
Clause-②: no
Metadata-protocol: none
维护者速读
ui/apps/console/src/components/FormPage.tsx新增的拒绝分支;ui/apps/console/src/App.tsx中/forms/:name移入权限布局的那一处。/_console/forms/showcase_project.form,应只看到一行红色的无权限提示,没有任何输入框;管理员打开同一链接仍是完整表单。What changes
/forms/NAMEmoves underConsolePermissionsScope. The app-less internal form route was a sibling of the console's permissions layout, underProtectedRoutealone, while its in-app twin/apps/APP/forms/NAMEsat under it. It is now a child of the same pathless layout route as/homeand/apps/APP/*, so both form URLs read the one/auth/me/permissionsanswer the console already holds. The URL is unchanged, deep links keep working, and a hop from Home or an app keeps the layout, so the answer is not asked again./f/SLUGstays outside it (anonymous, no answer, no request).FormPagerefuses up front. Once the form has loaded (it needs the form view to know its object), internal mode asks the affordance map's form row throughresolveAffordancefrom@object-ui/core, the predicate the app's own create and edit forms read:createFormFields(the create grant) for a create form,editFormFields(the update grant) for an edit form (?recordId=), each intersected with the object's effective API operations. Refused, the page draws the submit-time refusal's own sentence (form.noPermissionToSave, the one console FormPage: a refused create shows the raw server JSON envelope to the end user ("Create failed (403): {"error":…}) #29019's PR fix(console): a refused form submit says a localized sentence, never the server's response body #29184 uses) in arole="alert"banner and no field, no Submit. With the grant, nothing changes. No new i18n key, no metadata key, no server change.usePermissions()reads every grant open, so/f/SLUGand every existingFormPagetest behave as before.Tests
FormPage.upfrontWriteRefusal-29187.test.tsx(8 cases, realMePermissionsProviderfed the served payload shape): create without the create grant is refused with no textbox and no POST, on/forms/NAMEand/apps/APP/forms/NAME; create with it renders the form; the update grant alone does not open a create form; an edit form without the update grant is refused even with create; with it the form renders prefilled;/f/SLUGdraws its fields both under a no-create answer and with no answer at all.FormPage.routePermissions-29187.test.tsx(4 cases, realApproute tree andConsolePermissionsScope):/forms/NAMErenders under the answer, asked once; the loading screen shows before it;/homethen a form link asks/auth/me/permissionsonce in total;/f/SLUGhas no permission context and makes no request.mode === 'internal' &&in the new guard with a never-true test (node scripts/ablation-replace.mjs, restored togit diff HEADempty) reds exactly the four refusal cases; the four grant and public cases stay green.Acceptance notes
/forms/NAMEdeep link. The permission check costs one request,/auth/me/permissions. The same layout also holdsLauncherAppsProvider, so a cold deep link now asks/me/appstoo, as/homedoes: the form page's header launcher now narrows the apps it offers the way Home's does, where before it listed every app. A hop from Home or an app asks neither again.FormPage's object payload keeps onlyname,label,fieldsandfieldGroups, soresolveAffordanceis given noobjectSchemaand an object-leveluserActionsopt-out or a managed bucket does not refuse here; the grant and the effective API operations do. The card asked for the grant; widening the payload is a separate change.Verification
Live on a fresh showcase (
pnpm dev -- --fresh, source Console on Vite), a member created throughauth/admin/create-user, holding only theeveryonebaseline:showcase_projectread only,showcase_taskread + create, no edit. Before =mainat5780fa49, after = this branch./forms/showcase_project.form/apps/showcase_app/forms/showcase_project.form/forms/showcase_task.form(create allowed)/forms/showcase_task.form?recordId=ID(no edit)/f/contact-usScreenshots for every row (
before-*.png,after-*.png) are in the project folderissue-29187/.Gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 33 commands for this diff; each ran locally and exited 0, reconciled with--ran(the list is in the os-dev report on the card). Also:pnpm --filter @object-ui/console run type-checkexit 0; eslint on the four touched files, 0 errors; the FormPage, InternalFormRoute andApp.*console suites plusaffordanceGrantMap-12082.test.tsx(the census that refuses a CRUD grant read outside the map), 51 files / 474 tests green. All of the above reran green on the merged headc9f31cf0(main with #29322 and #29302): 33/33 derived gates exit 0 (--ran: 33 run, 0 NOT-MEASURED), the console suites 53 files / 484 tests,vitest run scripts/169 files. The last merge of main (e8cea601) touched onlyui/apps/console/src/main.tsx,vite.config.tsandtsconfig.node.jsonin this area; on it the console type-check (after rebuilding the@object-ui/mobiledist that merge moved) and the two new files plusApp.homePermissions-12700(17 tests) are green.Generated by Claude Code