Skip to content

Commit 4fd99eb

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
fix(quickbooks): sanitize customer tax identifiers
1 parent bf2a856 commit 4fd99eb

5 files changed

Lines changed: 70 additions & 2 deletions

File tree

apps/sim/tools/quickbooks/create_customer.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
quickBooksEmailAddress,
1818
quickBooksPhoneNumber,
1919
requiredQuickBooksString,
20+
sanitizeQuickBooksCustomer,
2021
transformQuickBooksMutationResponse,
2122
} from '@/tools/quickbooks/utils'
2223
import type { ToolConfig } from '@/tools/types'
@@ -123,7 +124,11 @@ export const quickbooksCreateCustomerTool: ToolConfig<
123124
maxResponseBytes: QUICKBOOKS_MAX_RESPONSE_BYTES,
124125
},
125126
transformResponse: (response) =>
126-
transformQuickBooksMutationResponse<QuickBooksCustomer>(response, 'Customer'),
127+
transformQuickBooksMutationResponse<QuickBooksCustomer>(
128+
response,
129+
'Customer',
130+
sanitizeQuickBooksCustomer
131+
),
127132
outputs: {
128133
record: {
129134
type: 'json',

apps/sim/tools/quickbooks/quickbooks.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,35 @@ describe('QuickBooks master-data reader', () => {
397397
expect(byIdResult.output.item).not.toHaveProperty('TaxIdentifier')
398398
})
399399

400+
it('removes customer tax identifiers from list and by-ID output', async () => {
401+
const customer = {
402+
Id: '4',
403+
SyncToken: '1',
404+
DisplayName: 'Sanitized Customer',
405+
TaxIdentifier: 'sensitive-tax-id',
406+
}
407+
const customerParams: QuickBooksReadMasterDataParams = {
408+
...listParams,
409+
recordType: 'customer',
410+
}
411+
412+
const listResult = await quickbooksReadMasterDataTool.transformResponse!(
413+
Response.json({ QueryResponse: { Customer: [customer] } }),
414+
customerParams
415+
)
416+
expect(listResult.output.items?.[0]).toEqual({
417+
Id: '4',
418+
SyncToken: '1',
419+
DisplayName: 'Sanitized Customer',
420+
})
421+
422+
const byIdResult = await quickbooksReadMasterDataTool.transformResponse!(
423+
Response.json({ Customer: customer }),
424+
{ ...customerParams, readMode: 'by_id', recordId: '4' }
425+
)
426+
expect(byIdResult.output.item).not.toHaveProperty('TaxIdentifier')
427+
})
428+
400429
it('rejects missing IDs, unknown types and unknown modes before a request', () => {
401430
const requestUrl = quickbooksReadMasterDataTool.request.url as (
402431
params: QuickBooksReadMasterDataParams
@@ -556,6 +585,27 @@ describe('QuickBooks customer and vendor mutations', () => {
556585
})
557586
}
558587
})
588+
589+
it('removes customer tax identifiers from mutation output', async () => {
590+
const response = {
591+
Customer: {
592+
Id: '22',
593+
SyncToken: '0',
594+
DisplayName: 'Sanitized Customer',
595+
TaxIdentifier: 'sensitive-tax-id',
596+
},
597+
time: 'test-time',
598+
}
599+
600+
for (const tool of [quickbooksCreateCustomerTool, quickbooksUpdateCustomerTool]) {
601+
const result = await tool.transformResponse!(Response.json(response))
602+
expect(result.output.record).toEqual({
603+
Id: '22',
604+
SyncToken: '0',
605+
DisplayName: 'Sanitized Customer',
606+
})
607+
}
608+
})
559609
})
560610

561611
describe('QuickBooks item mutations', () => {

apps/sim/tools/quickbooks/read_master_data.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ErrorExtractorId } from '@/tools/error-extractors'
22
import { QUICKBOOKS_MAX_RESPONSE_BYTES } from '@/tools/quickbooks/client'
33
import type {
44
QuickBooksAddress,
5+
QuickBooksCustomer,
56
QuickBooksEmployee,
67
QuickBooksMasterDataRecord,
78
QuickBooksReadMasterDataParams,
@@ -14,6 +15,7 @@ import {
1415
buildQuickBooksQueryUrl,
1516
getQuickBooksMasterDataEntity,
1617
getQuickBooksToolHeaders,
18+
sanitizeQuickBooksCustomer,
1719
sanitizeQuickBooksVendor,
1820
transformQuickBooksEntityResponse,
1921
transformQuickBooksListResponse,
@@ -114,6 +116,7 @@ function sanitizeMasterDataRecord(
114116
value: QuickBooksMasterDataRecord
115117
): QuickBooksMasterDataRecord {
116118
if (recordType === 'employee') return sanitizeEmployee(value)
119+
if (recordType === 'customer') return sanitizeQuickBooksCustomer(value as QuickBooksCustomer)
117120
if (recordType === 'vendor') return sanitizeQuickBooksVendor(value as QuickBooksVendor)
118121
return value
119122
}

apps/sim/tools/quickbooks/update_customer.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
quickBooksEmailAddress,
2020
quickBooksPhoneNumber,
2121
requiredQuickBooksString,
22+
sanitizeQuickBooksCustomer,
2223
transformQuickBooksMutationResponse,
2324
} from '@/tools/quickbooks/utils'
2425
import type { ToolConfig } from '@/tools/types'
@@ -151,7 +152,11 @@ export const quickbooksUpdateCustomerTool: ToolConfig<
151152
maxResponseBytes: QUICKBOOKS_MAX_RESPONSE_BYTES,
152153
},
153154
transformResponse: (response) =>
154-
transformQuickBooksMutationResponse<QuickBooksCustomer>(response, 'Customer'),
155+
transformQuickBooksMutationResponse<QuickBooksCustomer>(
156+
response,
157+
'Customer',
158+
sanitizeQuickBooksCustomer
159+
),
155160
outputs: {
156161
record: {
157162
type: 'json',

apps/sim/tools/quickbooks/utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { sanitizeQuickBooksFaultData } from '@/tools/quickbooks/fault'
1010
import type {
1111
QuickBooksActiveStatus,
1212
QuickBooksAddress,
13+
QuickBooksCustomer,
1314
QuickBooksListResponse,
1415
QuickBooksMasterDataRecord,
1516
QuickBooksMasterDataRecordType,
@@ -207,6 +208,10 @@ export function sanitizeQuickBooksVendor(vendor: QuickBooksVendor): QuickBooksVe
207208
return omit(vendor, ['TaxIdentifier']) as QuickBooksVendor
208209
}
209210

211+
export function sanitizeQuickBooksCustomer(customer: QuickBooksCustomer): QuickBooksCustomer {
212+
return omit(customer, ['TaxIdentifier']) as QuickBooksCustomer
213+
}
214+
210215
export function quickBooksWritableItemType(itemType: QuickBooksWritableItemType): string {
211216
const types: Record<QuickBooksWritableItemType, string> = {
212217
service: 'Service',

0 commit comments

Comments
 (0)