mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-10-22 18:13:27 +00:00
* ♻️ refactor: Take Typed Criteria, Not Mongo Filters, for Actions and Assistants `createActionMethods` and `createAssistantMethods` accepted `FilterQuery<T>`, putting Mongoose's query language in the package's public surface: every caller wrote raw Mongo, and no engine other than Mongo could satisfy the signatures. Both now take domain criteria — `ActionQuery` and `AssistantQuery` — naming concepts rather than stored fields, with an array meaning "any of these". A per-domain field map translates them, so `FilterQuery` survives only inside the two translators. `buildFilter` throws on a criterion the field map does not cover. Callers in `api/` are JavaScript and get no compile-time checking, and the server sets `strictQuery`, under which a silently dropped criterion widens the filter instead of narrowing it — an unscoped `findOne` returns an arbitrary document rather than none. Failing closed is the only safe default. `AssistantQuery.avatarFilepath` covers the avatar-authorization lookup, which queries a nested path no plain field name reaches. No behaviour change: every migrated call site produces the same filter as before. * 🧪 test: Update Avatar Authorization Assertion to Typed Criteria `validateImages.spec.js` asserted the old `{ 'avatar.filepath': { $in: [...] } }` call shape for `getAssistant`. The earlier sweep matched on `action_id`, `agent_id` and `assistant_id`, none of which appear in a dotted avatar path, so this one assertion was missed. The `getAgent` assertions in the same file keep the filter shape — that method still takes a `FilterQuery`. * 🔒 fix: Reject Unknown Criteria Before Omitting Undefined Ones `buildFilter` skipped a criterion whose value was `undefined` before checking it against the field map, so a JavaScript caller misspelling a key that happened to carry `undefined` — `deleteActions({ agent_id: maybeId })` — produced `{}` and reached `deleteMany` unscoped. That is the exact failure the guard exists to prevent, defeated by the order of the two checks. Validate every key first, then apply the undefined-omission rule. The lookup is an own-property check so inherited names cannot resolve through the field map's prototype: `{ toString: 'x' }` previously found `Function.prototype.toString`, passed the truthiness test, and wrote a garbage filter key instead of throwing. A recognized criterion left `undefined` is still omitted, so optional parameters keep working. * 🔒 fix: Reject Query Fragments as Criteria and Keep the Translator Internal Three review findings on the criteria translator, all of the same shape: the guard was narrower than the surface it protects. Criterion values are now validated as scalars or lists of scalars. `matchAny` copied any non-array through unchanged, so a JavaScript caller could pass `{ agentId: { $ne: null } }` and have the operator land verbatim in the filter — the fail-open case the field map exists to close. `null` is rejected too; it would have matched documents missing the field entirely. `matchAny`, `buildFilter` and `FieldMap` are no longer re-exported from the package barrel. They emit Mongo, and shipping them as public API undercut the point of the change; they were reachable as `require('@librechat/data-schemas') .buildFilter`. `OneOrMany` moves to `types/query` because the domain query types reference it and it names no engine — which also drops the `types` -> `utils` import. `loadActionSets` names `ActionQuery` through `import()` so the JSDoc type actually resolves. |
||
|---|---|---|
| .. | ||
| validateImages.spec.js | ||