Skip to content

Add automatic OData filter sanitization#106

Merged
alexisandreason merged 10 commits into
masterfrom
feat/odata-filter-sanitization
Jun 10, 2026
Merged

Add automatic OData filter sanitization#106
alexisandreason merged 10 commits into
masterfrom
feat/odata-filter-sanitization

Conversation

@alexisandreason

@alexisandreason alexisandreason commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds model/odata.ts with escaping primitives (odataString, odataValue) and a composable Filter builder that automatically escapes string values — fixing searches that broke when a value contained a single quote (e.g. an email/name like O'Brien).
  • Adds Filter.contains(field, value) for contains(...) predicates, escaping the value via odataString and composing with .and/.or/Filter.any like the other builders.
  • Widens QueryContext.setFilter to accept string | Filter (non-breaking — existing string callers are unchanged) and exports the new module from index.ts.
  • Migrates the highest-risk user-supplied string filters (UserName, DisplayName) in famis_client.ts to the Filter builder. Numeric-ID filters are intentionally left as-is and can be migrated incrementally.
  • Filter composition is precedence-safe: composite operands are parenthesized when combined, since OData binds and tighter than or.

Design and implementation plan: docs/superpowers/specs/2026-06-02-odata-filter-sanitization-design.md, docs/superpowers/plans/2026-06-02-odata-filter-sanitization.md.

Test Plan

  • Unit tests for odata.ts (escaping, type dispatch, builder composition incl. precedence safety)
  • Unit tests for Filter.contains (escaping + composition)
  • QueryContext.setFilter(Filter) renders the escaped $filter end-to-end via URL parsing
  • tsc build clean

🤖 Generated with Claude Code

Alexis Lasher and others added 10 commits June 2, 2026 11:26
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Introduce a composite flag so or/any results parenthesize themselves
only when combined with and, preventing the OData operator-precedence
trap where 'A or B and C' is silently misread as 'A or (B and C)'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@alphahlee

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

@alexisandreason alexisandreason merged commit 6ab9690 into master Jun 10, 2026
2 checks passed
@alexisandreason alexisandreason deleted the feat/odata-filter-sanitization branch June 10, 2026 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants