Repository navigation
fix(objectql): enforce per-option visibleWhen on checkboxes + string-match option values (objectui#2729) - #3350
Merged
Conversation
…ption values by string (objectui#2729) Server-side per-option gating covered select/multiselect/radio but two holes let gated values through on write: - checkboxes was excluded from CHOICE_FIELD_TYPES, so a gated `checkboxes` option (client widget cascades like multiselect since objectui#2715) was hidden in the UI but accepted from a crafted write. Now enforced element-wise on insert/update/bulk-update like multiselect. - Option matching used strict `===` while the enum validator compares by String(...); a numeric option value sent as a string passed the enum check but missed its visibleWhen gate (fail-open). Now coerces both sides. select/multiselect/radio behavior unchanged; fail-open on unbound current_user / unevaluable predicates preserved. Adds checkboxes + coercion cases to rule-validator.option-visibility.test.ts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 13 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Jul 20, 2026
…d + Console) Continues the v16 page from the latest front/back-end code. Since the rc.0 cut, 9 backend changesets landed and the objectui pin advanced 94d4876 -> af1b0db (objectui objectstack-ai#2706-objectstack-ai#2736). Sourced from each repo's own changesets. - Retitles the now-stale 'pending the next console pin' subsection: those 4 frontend items (objectui#2701/objectstack-ai#2706/objectstack-ai#2707/objectstack-ai#2708) are now bundled as the pin advanced; points to the new running section. - Adds a 'Landed since 16.0.0-rc.0' section: - Breaking/behavior: aiStudio/aiSeat alias removal (objectstack-ai#3308); date-arithmetic now a build-time error (objectstack-ai#3306); checkboxes per-option visibleWhen + string option matching (objectstack-ai#3350). - New backend: formula null-guard/floor/ceil (objectstack-ai#3306); engine-owned managedBy bucket (ADR-0103 addendum, objectstack-ai#3343); approvals viewer gating (objectstack-ai#3344) + decision attachments (objectstack-ai#3332); discovery transactionalBatch bit (objectstack-ai#3298); action resultDialog i18n (objectstack-ai#3347); collab-notification/storage localization + wired notifications REST routes (objectstack-ai#3354). - Console (now bundled): option-widget visibleWhen parity, approvals-inbox server-viewer gating + composer retirement, related-list pagination, inline-analytics renderer retirement, authenticated api-fetch threading, result-dialog i18n, engine-owned bucket UI, write-failure surfacing. - Adds aiStudio/aiSeat and date-arithmetic to the upgrade checklist; updates the Console-section intro for the advanced pin. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AHVoqyH9VAjmbyMN1Ri2jf
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Aug 17, 2026
…ectstack-ai#8886) (objectstack-ai#8912) The v16 page and its index entry still described the train as published as `16.0.0-rc.0`. Tags say otherwise: `@objectstack/spec@16.0.0-rc.0` (2026-07-19), `-rc.1` (2026-07-20), `16.0.0` (2026-07-21), `16.1.0` (2026-07-22). The series went GA, took a minor, and closed when 17.0.0 shipped on 2026-08-14. Four stale surfaces on the page, not one: 1. The release-status blockquote — rewritten as shipped, following the shape objectstack-ai#8882 set for v17. The "section headings say 16.0.0 for brevity" sentence is dropped (it explained a pre-mode convention that no longer exists); the trailing 15.1.1 cross-reference is kept verbatim — it is still true. 2. "Console vs. pin" said the pin "has since advanced to `af1b0db` on `main`". That advance released: changeset 1965549 bundles `af1b0db96e44` in `@objectstack/console` 16.0.0-rc.1. 3. "Console changes after the `rc.0` pin" carried the same `on main` framing. 4. The `Landed since 16.0.0-rc.0` window was left **open** ("roll into the next 16.0 RC"). It is closed against what actually released it, in the shape the v17 windows use. Every entry in it maps to a changeset consumed at the `16.0.0-rc.1` cut — objectstack-ai#3308 (06ff734), objectstack-ai#3347 (6289ec3), objectstack-ai#3298 (bfa3c3f), objectstack-ai#3306 (7125007), objectstack-ai#3343 (62a2117), objectstack-ai#3350 (674457a), objectstack-ai#3332 (e412fb6), objectstack-ai#3344 (8efa395), objectstack-ai#3354 (ee0a499) and the console pin (1965549) — and the 16.0.0 GA changelog sections re-list rc.0 + rc.1, the signature of `changeset pre exit`, so the window shipped in 16.0.0. The 16.1.0 minor is named as the line's final release but deliberately not documented: its content is out of this PR's scope. Claude-Session: https://claude.ai/code/session_011RB4waLuNbdruCo6X9oobm Co-authored-by: Claude <noreply@anthropic.com>
This branch was successfully deployed
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.
Addresses objectstack-ai/objectui#2729 (server-side enforcement of role-gated / dependent option values).
Context
Server-side per-option
visibleWhenenforcement already exists (packages/objectql/src/validation/rule-validator.ts→evaluateOptionVisibility, wired into insert / single-update / bulk-update). Investigating objectui#2729 surfaced that it coveredselect/multiselect/radiobut left two holes that let gated values through on write — the exact "client hides it, server must reject it" boundary the issue is about.Fixes
checkboxeswas not enforced.CHOICE_FIELD_TYPESomittedcheckboxes, sofieldHasOptionVisibilityreturned false for it and its options were never re-evaluated. Since objectui#2735 shipped client-sidecheckboxescascading, a gatedcheckboxesoption was hidden in the UI yet accepted from a crafted write. Addedcheckboxesto the enforced set — picked values are now checked element-wise against each option'svisibleWhen(record +current_user), likemultiselect. (checkboxesis already treated as a multi-value option field by the enum validator, so this closes an inconsistency between the two validators.)Numeric option values could slip the gate. Option matching used strict
===, but the enum-membership validator (record-validator.ts) compares byString(...). A numeric option value submitted as a string (a normal REST/JSON round-trip) passed the enum check but itsvisibleWhengate found no matching option and fail-opened. Matching now coerces both sides withString(...), so the enum and visibility validators agree on which option a written value denotes.Not changed / by design
select/multiselect/radiobehavior is unchanged.current_user(system writes) or unevaluable predicates is preserved — a broken cascade predicate must never brick a write; authorization gating depends on the engine bindingcurrent_user, as before.dependsOnremains a client form-gating hint only; server enforcement keys off each option'svisibleWhen(a cascade parent is expressed inside the child's predicate, e.g.record.country == 'cn'), matching the existing design.Tests
rule-validator.option-visibility.test.ts:checkboxeselement-wise gating (+needsPriorRecord), and numeric-value coercion (both are real regression guards — they fail on the pre-fix code).src/validation/+engine.test.ts(206 passed) andplugin.integration.test.tsreal-registry path (36 passed).tsc --noEmitclean;eslint0 errors (one pre-existing unrelatedno-newwarning).🤖 Generated with Claude Code