Skip to content

Commit efd15fe

Browse files
committed
fix(salesforce,google_contacts): sanitize SOQL field lists, warm contact search cache
- validate fields/orderBy as dotted SOQL paths (depth <= 5) instead of a charset allowlist, so a space-separated clause cannot be appended - clamp limit to the REST query resource's 1-2000 batch ceiling - drop unreachable !response.ok branches in the update_* tools - send the documented warmup request before people.searchContacts - clamp pageSize per operation (list 1000, search 30)
1 parent 52cfcce commit efd15fe

67 files changed

Lines changed: 2213 additions & 314 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/sim/blocks/blocks/google_contacts.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@ import { AuthMode, IntegrationType } from '@/blocks/types'
55
import { SERVICE_ACCOUNT_SUBBLOCKS } from '@/blocks/utils'
66
import type { GoogleContactsResponse } from '@/tools/google_contacts/types'
77

8+
/**
9+
* Per-operation `pageSize` ceilings. `people.connections.list` accepts 1–1000
10+
* (default 100), while `people:searchContacts` silently caps anything above 30
11+
* to 30 (default 10). One shared subBlock feeds both, so the value is clamped
12+
* to the ceiling of whichever operation is selected rather than sending a
13+
* number the target operation would quietly reduce.
14+
* @see https://developers.google.com/people/api/rest/v1/people.connections/list
15+
* @see https://developers.google.com/people/api/rest/v1/people/searchContacts
16+
*/
17+
const PAGE_SIZE_MAX_BY_OPERATION: Record<string, number> = {
18+
list: 1000,
19+
search: 30,
20+
}
21+
822
export const GoogleContactsBlock: BlockConfig<GoogleContactsResponse> = {
923
type: 'google_contacts',
1024
name: 'Google Contacts',
@@ -193,7 +207,8 @@ export const GoogleContactsBlock: BlockConfig<GoogleContactsResponse> = {
193207
id: 'pageSize',
194208
title: 'Page Size',
195209
type: 'short-input',
196-
placeholder: '100',
210+
placeholder: 'Number of results',
211+
tooltip: 'List accepts 1–1000 (default 100). Search accepts 1–30 (default 10).',
197212
condition: { field: 'operation', value: ['list', 'search'] },
198213
mode: 'advanced',
199214
},
@@ -253,9 +268,12 @@ export const GoogleContactsBlock: BlockConfig<GoogleContactsResponse> = {
253268

254269
const processedParams: Record<string, any> = { ...rest }
255270

256-
// Convert pageSize to number if provided
257-
if (processedParams.pageSize && typeof processedParams.pageSize === 'string') {
258-
processedParams.pageSize = Number.parseInt(processedParams.pageSize, 10)
271+
const pageSizeMax = PAGE_SIZE_MAX_BY_OPERATION[operation]
272+
if (pageSizeMax !== undefined && processedParams.pageSize !== undefined) {
273+
const parsed = Number.parseInt(String(processedParams.pageSize), 10)
274+
processedParams.pageSize = Number.isNaN(parsed)
275+
? undefined
276+
: Math.min(Math.max(parsed, 1), pageSizeMax)
259277
}
260278

261279
return {

apps/sim/blocks/blocks/linkedin.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export const LinkedInBlock: BlockConfig<LinkedInResponse> = {
8383
options: [
8484
{ label: 'Public', id: 'PUBLIC' },
8585
{ label: 'Connections Only', id: 'CONNECTIONS' },
86+
{ label: 'Logged-In Members Only', id: 'LOGGED_IN' },
8687
],
8788
condition: {
8889
field: 'operation',
@@ -126,7 +127,10 @@ export const LinkedInBlock: BlockConfig<LinkedInResponse> = {
126127
operation: { type: 'string', description: 'Operation to perform' },
127128
oauthCredential: { type: 'string', description: 'LinkedIn access token' },
128129
text: { type: 'string', description: 'Post text content' },
129-
visibility: { type: 'string', description: 'Post visibility (PUBLIC or CONNECTIONS)' },
130+
visibility: {
131+
type: 'string',
132+
description: 'Post visibility (PUBLIC, CONNECTIONS, or LOGGED_IN)',
133+
},
130134
},
131135
outputs: {
132136
success: { type: 'boolean', description: 'Operation success status' },

apps/sim/blocks/blocks/serper.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ export const SerperBlock: BlockConfig<SearchResponse> = {
3737
title: 'Search Type',
3838
type: 'dropdown',
3939
options: [
40-
{ label: 'search', id: 'search' },
41-
{ label: 'news', id: 'news' },
42-
{ label: 'places', id: 'places' },
43-
{ label: 'images', id: 'images' },
44-
{ label: 'videos', id: 'videos' },
45-
{ label: 'shopping', id: 'shopping' },
40+
{ label: 'Search', id: 'search' },
41+
{ label: 'News', id: 'news' },
42+
{ label: 'Places', id: 'places' },
43+
{ label: 'Images', id: 'images' },
44+
{ label: 'Videos', id: 'videos' },
45+
{ label: 'Shopping', id: 'shopping' },
46+
{ label: 'Scholar', id: 'scholar' },
47+
{ label: 'Patents', id: 'patents' },
4648
],
4749
value: () => 'search',
4850
},
@@ -106,7 +108,11 @@ export const SerperBlock: BlockConfig<SearchResponse> = {
106108
type: { type: 'string', description: 'Search type' },
107109
},
108110
outputs: {
109-
searchResults: { type: 'json', description: 'Search results data' },
111+
searchResults: {
112+
type: 'json',
113+
description:
114+
'Results for the requested vertical: [{title, link, snippet, position, date, imageUrl, thumbnailUrl, source, channel, rating, ratingCount, address, latitude, longitude, category, phoneNumber, website, price, delivery, duration}]. Only title and position are always present; the rest depend on the vertical'
115+
},
110116
knowledgeGraph: {
111117
type: 'json',
112118
description: 'Google knowledge panel. Web search vertical only, when Google renders one',

apps/sim/tools/elasticsearch/bulk.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
ElasticsearchBulkResponse,
44
} from '@/tools/elasticsearch/types'
55
import { buildAuthHeaders, buildBaseUrl, safeIndexPathSegment } from '@/tools/elasticsearch/utils'
6+
import { ErrorExtractorId } from '@/tools/error-extractors'
67
import type { ToolConfig } from '@/tools/types'
78

89
export const bulkTool: ToolConfig<ElasticsearchBulkParams, ElasticsearchBulkResponse> = {
@@ -11,6 +12,7 @@ export const bulkTool: ToolConfig<ElasticsearchBulkParams, ElasticsearchBulkResp
1112
description:
1213
'Perform multiple index, create, delete, or update operations in a single request for high performance.',
1314
version: '1.0.0',
15+
errorExtractor: ErrorExtractorId.ELASTICSEARCH_ERRORS,
1416

1517
params: {
1618
deploymentType: {

apps/sim/tools/elasticsearch/cluster_health.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
ElasticsearchClusterHealthResponse,
44
} from '@/tools/elasticsearch/types'
55
import { buildAuthHeaders, buildBaseUrl, normalizeEsDuration } from '@/tools/elasticsearch/utils'
6+
import { ErrorExtractorId } from '@/tools/error-extractors'
67
import type { ToolConfig } from '@/tools/types'
78

89
export const clusterHealthTool: ToolConfig<
@@ -13,6 +14,7 @@ export const clusterHealthTool: ToolConfig<
1314
name: 'Elasticsearch Cluster Health',
1415
description: 'Get the health status of the Elasticsearch cluster.',
1516
version: '1.0.0',
17+
errorExtractor: ErrorExtractorId.ELASTICSEARCH_ERRORS,
1618

1719
params: {
1820
deploymentType: {

apps/sim/tools/elasticsearch/cluster_stats.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
ElasticsearchClusterStatsResponse,
44
} from '@/tools/elasticsearch/types'
55
import { buildAuthHeaders, buildBaseUrl } from '@/tools/elasticsearch/utils'
6+
import { ErrorExtractorId } from '@/tools/error-extractors'
67
import type { ToolConfig } from '@/tools/types'
78

89
export const clusterStatsTool: ToolConfig<
@@ -13,6 +14,7 @@ export const clusterStatsTool: ToolConfig<
1314
name: 'Elasticsearch Cluster Stats',
1415
description: 'Get comprehensive statistics about the Elasticsearch cluster.',
1516
version: '1.0.0',
17+
errorExtractor: ErrorExtractorId.ELASTICSEARCH_ERRORS,
1618

1719
params: {
1820
deploymentType: {

apps/sim/tools/elasticsearch/count.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import type {
33
ElasticsearchCountResponse,
44
} from '@/tools/elasticsearch/types'
55
import { buildAuthHeaders, buildBaseUrl, safeIndexPathSegment } from '@/tools/elasticsearch/utils'
6+
import { ErrorExtractorId } from '@/tools/error-extractors'
67
import type { ToolConfig } from '@/tools/types'
78

89
export const countTool: ToolConfig<ElasticsearchCountParams, ElasticsearchCountResponse> = {
910
id: 'elasticsearch_count',
1011
name: 'Elasticsearch Count',
1112
description: 'Count documents matching a query in Elasticsearch.',
1213
version: '1.0.0',
14+
errorExtractor: ErrorExtractorId.ELASTICSEARCH_ERRORS,
1315

1416
params: {
1517
deploymentType: {

apps/sim/tools/elasticsearch/create_index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
ElasticsearchIndexResponse,
44
} from '@/tools/elasticsearch/types'
55
import { buildAuthHeaders, buildBaseUrl, safeIndexPathSegment } from '@/tools/elasticsearch/utils'
6+
import { ErrorExtractorId } from '@/tools/error-extractors'
67
import type { ToolConfig } from '@/tools/types'
78

89
export const createIndexTool: ToolConfig<
@@ -13,6 +14,7 @@ export const createIndexTool: ToolConfig<
1314
name: 'Elasticsearch Create Index',
1415
description: 'Create a new index with optional settings and mappings.',
1516
version: '1.0.0',
17+
errorExtractor: ErrorExtractorId.ELASTICSEARCH_ERRORS,
1618

1719
params: {
1820
deploymentType: {

apps/sim/tools/elasticsearch/delete_document.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
ElasticsearchDocumentResponse,
44
} from '@/tools/elasticsearch/types'
55
import { buildAuthHeaders, buildBaseUrl, safeIndexPathSegment } from '@/tools/elasticsearch/utils'
6+
import { ErrorExtractorId } from '@/tools/error-extractors'
67
import type { ToolConfig } from '@/tools/types'
78
import { safeUrlPathSegment } from '@/tools/url-path'
89

@@ -14,6 +15,7 @@ export const deleteDocumentTool: ToolConfig<
1415
name: 'Elasticsearch Delete Document',
1516
description: 'Delete a document from Elasticsearch by ID.',
1617
version: '1.0.0',
18+
errorExtractor: ErrorExtractorId.ELASTICSEARCH_ERRORS,
1719

1820
params: {
1921
deploymentType: {

apps/sim/tools/elasticsearch/delete_index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
ElasticsearchIndexResponse,
44
} from '@/tools/elasticsearch/types'
55
import { buildAuthHeaders, buildBaseUrl, safeIndexPathSegment } from '@/tools/elasticsearch/utils'
6+
import { ErrorExtractorId } from '@/tools/error-extractors'
67
import type { ToolConfig } from '@/tools/types'
78

89
export const deleteIndexTool: ToolConfig<
@@ -13,6 +14,7 @@ export const deleteIndexTool: ToolConfig<
1314
name: 'Elasticsearch Delete Index',
1415
description: 'Delete an index and all its documents. This operation is irreversible.',
1516
version: '1.0.0',
17+
errorExtractor: ErrorExtractorId.ELASTICSEARCH_ERRORS,
1618

1719
params: {
1820
deploymentType: {

0 commit comments

Comments
 (0)