@formio/uag 1.12.1 → 1.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/tools/fetchExternalData.js +2 -1
- package/lib/tools/findSubmission.js +18 -3
- package/lib/tools/utils.d.ts +20 -0
- package/lib/tools/utils.js +23 -0
- package/package.json +2 -2
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.fetchExternalData = void 0;
|
|
4
4
|
const template_1 = require("../template");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
5
6
|
const core_1 = require("@formio/core");
|
|
6
7
|
const SchemaBuilder_1 = require("./SchemaBuilder");
|
|
7
8
|
const lodash_1 = require("lodash");
|
|
@@ -251,7 +252,7 @@ async function fetchResourceData(component, search_value, authInfo, project, con
|
|
|
251
252
|
const query = {};
|
|
252
253
|
// Add search filter if provided
|
|
253
254
|
if (search_value && component.searchField) {
|
|
254
|
-
query[`data.${component.searchField}__regex`] = `/${search_value}/i`;
|
|
255
|
+
query[`data.${component.searchField}__regex`] = `/${(0, utils_1.escapeSearchPattern)(search_value)}/i`;
|
|
255
256
|
}
|
|
256
257
|
// Add component filter if configured (interpolate the filter string)
|
|
257
258
|
if (component.filter) {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.findSubmission = void 0;
|
|
4
4
|
const template_1 = require("../template");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
5
6
|
const lodash_1 = require("lodash");
|
|
6
7
|
const SchemaBuilder_1 = require("./SchemaBuilder");
|
|
7
8
|
const error = require('debug')('formio:uag:findSubmission:error');
|
|
@@ -34,19 +35,33 @@ const findSubmission = async (project) => {
|
|
|
34
35
|
}, true);
|
|
35
36
|
}
|
|
36
37
|
if (criterion.operator === 'regex') {
|
|
38
|
+
// The value is a pattern by request here, so it is passed through
|
|
39
|
+
// unescaped. It is still compiled first: the server drops a filter
|
|
40
|
+
// it cannot compile, which would widen the search instead of
|
|
41
|
+
// failing it, so a bad pattern is better reported back.
|
|
42
|
+
try {
|
|
43
|
+
new RegExp(criterion.search_value);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
return project.mcpResponse(template_1.ResponseTemplate.submissionSearchError, {
|
|
47
|
+
form: form.form,
|
|
48
|
+
searchQuery: search_query,
|
|
49
|
+
error: `"${criterion.search_value}" is not a valid regular expression for "${criterion.data_path}". Use the "contains" operator to search for it literally.`
|
|
50
|
+
}, true);
|
|
51
|
+
}
|
|
37
52
|
query[`data.${criterion.data_path}__regex`] = `/${criterion.search_value}/i`;
|
|
38
53
|
}
|
|
39
54
|
else if (criterion.operator === 'equals') {
|
|
40
55
|
query[`data.${criterion.data_path}`] = criterion.search_value;
|
|
41
56
|
}
|
|
42
57
|
else if (criterion.operator === 'contains') {
|
|
43
|
-
query[`data.${criterion.data_path}__regex`] = `/${criterion.search_value}/i`;
|
|
58
|
+
query[`data.${criterion.data_path}__regex`] = `/${(0, utils_1.escapeSearchPattern)(criterion.search_value)}/i`;
|
|
44
59
|
}
|
|
45
60
|
else if (criterion.operator === 'starts_with') {
|
|
46
|
-
query[`data.${criterion.data_path}__regex`] = `/^${criterion.search_value}/i`;
|
|
61
|
+
query[`data.${criterion.data_path}__regex`] = `/^${(0, utils_1.escapeSearchPattern)(criterion.search_value)}/i`;
|
|
47
62
|
}
|
|
48
63
|
else if (criterion.operator === 'ends_with') {
|
|
49
|
-
query[`data.${criterion.data_path}__regex`] = `/${criterion.search_value}$/i`;
|
|
64
|
+
query[`data.${criterion.data_path}__regex`] = `/${(0, utils_1.escapeSearchPattern)(criterion.search_value)}$/i`;
|
|
50
65
|
}
|
|
51
66
|
else if (criterion.operator === 'greater_than') {
|
|
52
67
|
query[`data.${criterion.data_path}__gt`] = criterion.search_value;
|
package/lib/tools/utils.d.ts
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
import { ZodRawShape } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Escape a literal value so it can be carried in a `__regex` query parameter.
|
|
4
|
+
*
|
|
5
|
+
* Operators like "contains" promise a literal match, so every regular expression
|
|
6
|
+
* metacharacter in the value has to be neutered first. Left raw, a search for
|
|
7
|
+
* "joe.thompson@example.com" becomes a pattern whose dots match any character,
|
|
8
|
+
* and a value such as "[" is not a valid pattern at all — the server compiles
|
|
9
|
+
* these with a try/catch and silently drops the filter when compilation fails,
|
|
10
|
+
* which turns a narrow search into one that matches everything.
|
|
11
|
+
*
|
|
12
|
+
* Forward slashes get a further step. The server reads the parameter as
|
|
13
|
+
* `/pattern/flags` and takes the pattern with `[^/]+`, so an embedded slash
|
|
14
|
+
* truncates the pattern and the remainder is parsed as flags — again dropping
|
|
15
|
+
* the filter. Writing it as the equivalent `\x2f` escape keeps the character
|
|
16
|
+
* out of the transport while still matching a literal slash.
|
|
17
|
+
*
|
|
18
|
+
* @param value - The literal text to search for.
|
|
19
|
+
* @returns The value as a regular expression pattern that matches it literally.
|
|
20
|
+
*/
|
|
21
|
+
export declare const escapeSearchPattern: (value: string) => string;
|
|
2
22
|
export type ToolInfo = {
|
|
3
23
|
name?: string;
|
|
4
24
|
title?: string;
|
package/lib/tools/utils.js
CHANGED
|
@@ -1,2 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.escapeSearchPattern = void 0;
|
|
4
|
+
const lodash_1 = require("lodash");
|
|
5
|
+
/**
|
|
6
|
+
* Escape a literal value so it can be carried in a `__regex` query parameter.
|
|
7
|
+
*
|
|
8
|
+
* Operators like "contains" promise a literal match, so every regular expression
|
|
9
|
+
* metacharacter in the value has to be neutered first. Left raw, a search for
|
|
10
|
+
* "joe.thompson@example.com" becomes a pattern whose dots match any character,
|
|
11
|
+
* and a value such as "[" is not a valid pattern at all — the server compiles
|
|
12
|
+
* these with a try/catch and silently drops the filter when compilation fails,
|
|
13
|
+
* which turns a narrow search into one that matches everything.
|
|
14
|
+
*
|
|
15
|
+
* Forward slashes get a further step. The server reads the parameter as
|
|
16
|
+
* `/pattern/flags` and takes the pattern with `[^/]+`, so an embedded slash
|
|
17
|
+
* truncates the pattern and the remainder is parsed as flags — again dropping
|
|
18
|
+
* the filter. Writing it as the equivalent `\x2f` escape keeps the character
|
|
19
|
+
* out of the transport while still matching a literal slash.
|
|
20
|
+
*
|
|
21
|
+
* @param value - The literal text to search for.
|
|
22
|
+
* @returns The value as a regular expression pattern that matches it literally.
|
|
23
|
+
*/
|
|
24
|
+
const escapeSearchPattern = (value) => (0, lodash_1.escapeRegExp)(value).replace(/\//g, '\\x2f');
|
|
25
|
+
exports.escapeSearchPattern = escapeSearchPattern;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formio/uag",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.2",
|
|
4
4
|
"mcpName": "io.form/uag",
|
|
5
5
|
"description": "The Form.io Universal Agent Gateway (UAG).",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"author": "Form.io Developers",
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@formio/appserver": "^2.13.
|
|
33
|
+
"@formio/appserver": "^2.13.2",
|
|
34
34
|
"@formio/core": "2.8.0",
|
|
35
35
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
36
36
|
"cors": "^2.8.6",
|