@easyflow/javascript-sdk 2.1.7 → 2.1.9
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/README.md +294 -713
- package/dist/index.d.ts +421 -0
- package/package.json +19 -6
- package/.babelrc +0 -5
- package/.github/workflows/deploy-sdk-cf.yml +0 -49
- package/.github/workflows/release-sdk-cdn.yml +0 -144
- package/.github/workflows/release-sdk.yml +0 -112
- package/.prettierrc +0 -6
- package/CDN-DEPLOYMENT.md +0 -175
- package/DEMO.md +0 -258
- package/DEPLOYMENT.md +0 -224
- package/INTEGRATION-GUIDE.md +0 -521
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/easyflow-javascript-sdk/index.html +0 -116
- package/coverage/easyflow-javascript-sdk/libs/constants.mjs.html +0 -268
- package/coverage/easyflow-javascript-sdk/libs/errors.mjs.html +0 -271
- package/coverage/easyflow-javascript-sdk/libs/exception-handler.mjs.html +0 -148
- package/coverage/easyflow-javascript-sdk/libs/fingerprint.mjs.html +0 -895
- package/coverage/easyflow-javascript-sdk/libs/http.mjs.html +0 -502
- package/coverage/easyflow-javascript-sdk/libs/index.html +0 -266
- package/coverage/easyflow-javascript-sdk/libs/logger.mjs.html +0 -568
- package/coverage/easyflow-javascript-sdk/libs/sanitizer.mjs.html +0 -1099
- package/coverage/easyflow-javascript-sdk/libs/security.mjs.html +0 -733
- package/coverage/easyflow-javascript-sdk/libs/types.mjs.html +0 -508
- package/coverage/easyflow-javascript-sdk/libs/utils.mjs.html +0 -379
- package/coverage/easyflow-javascript-sdk/libs/validator.mjs.html +0 -2623
- package/coverage/easyflow-javascript-sdk/sdk.mjs.html +0 -2434
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -131
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/easyflow-javascript-sdk/index.html +0 -116
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/constants.mjs.html +0 -268
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/errors.mjs.html +0 -271
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/exception-handler.mjs.html +0 -148
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/fingerprint.mjs.html +0 -895
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/http.mjs.html +0 -502
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/index.html +0 -266
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/logger.mjs.html +0 -568
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/sanitizer.mjs.html +0 -1099
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/security.mjs.html +0 -733
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/types.mjs.html +0 -508
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/utils.mjs.html +0 -379
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/validator.mjs.html +0 -2623
- package/coverage/lcov-report/easyflow-javascript-sdk/sdk.mjs.html +0 -2434
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -131
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov.info +0 -1429
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -196
- package/dist/435.easyflow-sdk.min.js +0 -1
- package/dist/easyflow-sdk.min.js +0 -1
- package/dist/easyflow-sdk.min.js.LICENSE.txt +0 -1
- package/dist/index.html +0 -756
- package/docs/index.html +0 -775
- package/examples/lovable-integration.html +0 -410
- package/index.html +0 -981
- package/jest.config.js +0 -37
- package/jsdoc.json +0 -42
- package/libs/auto-integration.mjs +0 -333
- package/libs/constants.mjs +0 -61
- package/libs/constants.spec.js +0 -198
- package/libs/errors.mjs +0 -62
- package/libs/errors.spec.js +0 -178
- package/libs/exception-handler.mjs +0 -21
- package/libs/exception-handler.spec.js +0 -237
- package/libs/fingerprint.mjs +0 -270
- package/libs/http.mjs +0 -163
- package/libs/http.spec.js +0 -427
- package/libs/integration-wrapper.mjs +0 -285
- package/libs/logger.mjs +0 -161
- package/libs/logger.spec.js +0 -389
- package/libs/sanitizer.mjs +0 -340
- package/libs/sanitizer.spec.js +0 -583
- package/libs/security.mjs +0 -217
- package/libs/types.mjs +0 -141
- package/libs/utils.mjs +0 -368
- package/libs/utils.spec.js +0 -231
- package/libs/validator.mjs +0 -952
- package/libs/validator.spec.js +0 -615
- package/mocks/offer.mock.js +0 -77
- package/scripts/publish-npm.sh +0 -82
- package/sdk.mjs +0 -945
- package/sdk.spec.js +0 -796
- package/test-setup.cjs +0 -211
- package/test.html +0 -154
- package/webpack.config.cjs +0 -41
package/libs/sanitizer.spec.js
DELETED
|
@@ -1,583 +0,0 @@
|
|
|
1
|
-
import { jest } from '@jest/globals'
|
|
2
|
-
import { Sanitizer, sanitizeOrderData } from './sanitizer.mjs'
|
|
3
|
-
|
|
4
|
-
// Mock deepClone
|
|
5
|
-
jest.mock('./utils.mjs', () => ({
|
|
6
|
-
deepClone: jest.fn((data) => JSON.parse(JSON.stringify(data))),
|
|
7
|
-
}))
|
|
8
|
-
|
|
9
|
-
describe('Sanitizer', () => {
|
|
10
|
-
describe('sanitizeHeaders', () => {
|
|
11
|
-
test('should remove dangerous headers', () => {
|
|
12
|
-
const headers = {
|
|
13
|
-
'Content-Type': 'application/json',
|
|
14
|
-
'x-forwarded-for': 'malicious-ip',
|
|
15
|
-
Authorization: 'Bearer token',
|
|
16
|
-
'x-real-ip': 'another-malicious-ip',
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const result = Sanitizer.sanitizeHeaders(headers)
|
|
20
|
-
|
|
21
|
-
expect(result).toEqual({
|
|
22
|
-
'Content-Type': 'application/json',
|
|
23
|
-
Authorization: 'Bearer token',
|
|
24
|
-
})
|
|
25
|
-
expect(result['x-forwarded-for']).toBeUndefined()
|
|
26
|
-
expect(result['x-real-ip']).toBeUndefined()
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
test('should handle case-insensitive header names', () => {
|
|
30
|
-
const headers = {
|
|
31
|
-
'X-Forwarded-For': 'malicious-ip',
|
|
32
|
-
'X-REAL-IP': 'another-malicious-ip',
|
|
33
|
-
'Content-Type': 'application/json',
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const result = Sanitizer.sanitizeHeaders(headers)
|
|
37
|
-
|
|
38
|
-
expect(result).toEqual({
|
|
39
|
-
'Content-Type': 'application/json',
|
|
40
|
-
})
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
test('should return empty object for empty headers', () => {
|
|
44
|
-
const result = Sanitizer.sanitizeHeaders({})
|
|
45
|
-
expect(result).toEqual({})
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
test('should handle undefined headers', () => {
|
|
49
|
-
const result = Sanitizer.sanitizeHeaders(undefined)
|
|
50
|
-
expect(result).toEqual({})
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
test('should preserve safe headers', () => {
|
|
54
|
-
const headers = {
|
|
55
|
-
'Content-Type': 'application/json',
|
|
56
|
-
Authorization: 'Bearer token',
|
|
57
|
-
'User-Agent': 'Mozilla/5.0',
|
|
58
|
-
Accept: 'application/json',
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const result = Sanitizer.sanitizeHeaders(headers)
|
|
62
|
-
|
|
63
|
-
expect(result).toEqual(headers)
|
|
64
|
-
})
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
describe('sanitizeInput', () => {
|
|
68
|
-
test('should sanitize string with dangerous characters', () => {
|
|
69
|
-
const input = '<script>alert("xss")</script>'
|
|
70
|
-
const result = Sanitizer.sanitizeInput(input)
|
|
71
|
-
expect(result).toBe('scriptalert("xss")/script')
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
test('should remove javascript: protocol', () => {
|
|
75
|
-
const input = 'javascript:alert("xss")'
|
|
76
|
-
const result = Sanitizer.sanitizeInput(input)
|
|
77
|
-
expect(result).toBe('alert("xss")')
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
test('should remove data: protocol', () => {
|
|
81
|
-
const input = 'data:text/html,<script>alert("xss")</script>'
|
|
82
|
-
const result = Sanitizer.sanitizeInput(input)
|
|
83
|
-
expect(result).toBe('text/html,scriptalert("xss")/script')
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
test('should remove vbscript: protocol', () => {
|
|
87
|
-
const input = 'vbscript:msgbox("xss")'
|
|
88
|
-
const result = Sanitizer.sanitizeInput(input)
|
|
89
|
-
expect(result).toBe('msgbox("xss")')
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
test('should trim whitespace', () => {
|
|
93
|
-
const input = ' test value '
|
|
94
|
-
const result = Sanitizer.sanitizeInput(input)
|
|
95
|
-
|
|
96
|
-
expect(result).toBe('test value')
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
test('should return non-string values unchanged', () => {
|
|
100
|
-
expect(Sanitizer.sanitizeInput(123)).toBe(123)
|
|
101
|
-
expect(Sanitizer.sanitizeInput(true)).toBe(true)
|
|
102
|
-
expect(Sanitizer.sanitizeInput(null)).toBe(null)
|
|
103
|
-
expect(Sanitizer.sanitizeInput(undefined)).toBe(undefined)
|
|
104
|
-
expect(Sanitizer.sanitizeInput({})).toEqual({})
|
|
105
|
-
expect(Sanitizer.sanitizeInput([])).toEqual([])
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
test('should handle empty string', () => {
|
|
109
|
-
const result = Sanitizer.sanitizeInput('')
|
|
110
|
-
expect(result).toBe('')
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
test('should handle string with only dangerous characters', () => {
|
|
114
|
-
const input = '<>"\'&'
|
|
115
|
-
const result = Sanitizer.sanitizeInput(input)
|
|
116
|
-
expect(result).toBe('"\'')
|
|
117
|
-
})
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
describe('sanitizeCreditCard', () => {
|
|
121
|
-
test('should sanitize all credit card fields', () => {
|
|
122
|
-
const creditCard = {
|
|
123
|
-
cardNumber: '4111 1111 1111 1111',
|
|
124
|
-
cvv: '123',
|
|
125
|
-
month: '12',
|
|
126
|
-
year: '2025',
|
|
127
|
-
holderName: 'John Doe',
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const result = Sanitizer.sanitizeCreditCard(creditCard)
|
|
131
|
-
|
|
132
|
-
expect(result).toEqual({
|
|
133
|
-
cardNumber: '4111 1111 1111 1111',
|
|
134
|
-
cvv: '123',
|
|
135
|
-
month: '12',
|
|
136
|
-
year: '2025',
|
|
137
|
-
holderName: 'John Doe',
|
|
138
|
-
})
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
test('should sanitize credit card with dangerous characters', () => {
|
|
142
|
-
const creditCard = {
|
|
143
|
-
cardNumber: '4111<script>1111</script>1111',
|
|
144
|
-
cvv: '123',
|
|
145
|
-
month: '12',
|
|
146
|
-
year: '2025',
|
|
147
|
-
holderName: '<script>alert("xss")</script>John Doe',
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const result = Sanitizer.sanitizeCreditCard(creditCard)
|
|
151
|
-
|
|
152
|
-
expect(result).toEqual({
|
|
153
|
-
cardNumber: '4111script1111/script1111',
|
|
154
|
-
cvv: '123',
|
|
155
|
-
month: '12',
|
|
156
|
-
year: '2025',
|
|
157
|
-
holderName: 'scriptalert("xss")/scriptJohn Doe',
|
|
158
|
-
})
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
test('should handle missing fields', () => {
|
|
162
|
-
const creditCard = {
|
|
163
|
-
cardNumber: '4111111111111111',
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const result = Sanitizer.sanitizeCreditCard(creditCard)
|
|
167
|
-
|
|
168
|
-
expect(result).toEqual({
|
|
169
|
-
cardNumber: '4111111111111111',
|
|
170
|
-
cvv: undefined,
|
|
171
|
-
month: undefined,
|
|
172
|
-
year: undefined,
|
|
173
|
-
holderName: undefined,
|
|
174
|
-
})
|
|
175
|
-
})
|
|
176
|
-
})
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
describe('sanitizeOrderData', () => {
|
|
180
|
-
test('should sanitize buyer information', () => {
|
|
181
|
-
const order = {
|
|
182
|
-
buyer: {
|
|
183
|
-
name: '<script>alert("xss")</script>John Doe',
|
|
184
|
-
email: 'john@example.com',
|
|
185
|
-
document: {
|
|
186
|
-
number: '123<script>456</script>789',
|
|
187
|
-
type: 'CPF',
|
|
188
|
-
},
|
|
189
|
-
phone: {
|
|
190
|
-
number: '119999<script>99999</script>',
|
|
191
|
-
areaCode: '11',
|
|
192
|
-
},
|
|
193
|
-
address: {
|
|
194
|
-
zipCode: '01234<script>567</script>',
|
|
195
|
-
street: 'Main Street',
|
|
196
|
-
complement: 'Apt 123',
|
|
197
|
-
neighborhood: 'Downtown',
|
|
198
|
-
city: 'São Paulo',
|
|
199
|
-
state: 'SP',
|
|
200
|
-
number: '123',
|
|
201
|
-
},
|
|
202
|
-
},
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const result = sanitizeOrderData(order)
|
|
206
|
-
|
|
207
|
-
expect(result.buyer.name).toBe('scriptalert("xss")/scriptJohn Doe')
|
|
208
|
-
expect(result.buyer.email).toBe('john@example.com')
|
|
209
|
-
expect(result.buyer.document.number).toBe('123script456/script789')
|
|
210
|
-
expect(result.buyer.document.type).toBe('CPF')
|
|
211
|
-
expect(result.buyer.phone.number).toBe('119999script99999/script')
|
|
212
|
-
expect(result.buyer.phone.areaCode).toBe('11')
|
|
213
|
-
expect(result.buyer.address.zipCode).toBe('01234script567/script')
|
|
214
|
-
expect(result.buyer.address.street).toBe('Main Street')
|
|
215
|
-
expect(result.buyer.address.complement).toBe('Apt 123')
|
|
216
|
-
expect(result.buyer.address.neighborhood).toBe('Downtown')
|
|
217
|
-
expect(result.buyer.address.city).toBe('São Paulo')
|
|
218
|
-
expect(result.buyer.address.state).toBe('SP')
|
|
219
|
-
expect(result.buyer.address.number).toBe('123')
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
test('should sanitize delivery address', () => {
|
|
223
|
-
const order = {
|
|
224
|
-
buyer: {
|
|
225
|
-
deliveryAddress: {
|
|
226
|
-
zipCode: '01234<script>567</script>',
|
|
227
|
-
street: 'Delivery Street',
|
|
228
|
-
complement: 'Apt 456',
|
|
229
|
-
neighborhood: 'Uptown',
|
|
230
|
-
city: 'Rio de Janeiro',
|
|
231
|
-
state: 'RJ',
|
|
232
|
-
number: '456',
|
|
233
|
-
},
|
|
234
|
-
},
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const result = sanitizeOrderData(order)
|
|
238
|
-
|
|
239
|
-
expect(result.buyer.deliveryAddress.zipCode).toBe(
|
|
240
|
-
'01234script567/script'
|
|
241
|
-
)
|
|
242
|
-
expect(result.buyer.deliveryAddress.street).toBe('Delivery Street')
|
|
243
|
-
expect(result.buyer.deliveryAddress.complement).toBe('Apt 456')
|
|
244
|
-
expect(result.buyer.deliveryAddress.neighborhood).toBe('Uptown')
|
|
245
|
-
expect(result.buyer.deliveryAddress.city).toBe('Rio de Janeiro')
|
|
246
|
-
expect(result.buyer.deliveryAddress.state).toBe('RJ')
|
|
247
|
-
expect(result.buyer.deliveryAddress.number).toBe('456')
|
|
248
|
-
})
|
|
249
|
-
|
|
250
|
-
test('should sanitize credit card payments', () => {
|
|
251
|
-
const order = {
|
|
252
|
-
payments: [
|
|
253
|
-
{
|
|
254
|
-
method: 'credit-card',
|
|
255
|
-
creditCard: {
|
|
256
|
-
cardNumber: '4111<script>1111</script>1111',
|
|
257
|
-
cvv: '123',
|
|
258
|
-
month: '12',
|
|
259
|
-
year: '2025',
|
|
260
|
-
holderName: '<script>alert("xss")</script>John Doe',
|
|
261
|
-
},
|
|
262
|
-
},
|
|
263
|
-
],
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
const result = sanitizeOrderData(order)
|
|
267
|
-
|
|
268
|
-
expect(result.payments[0].creditCard.cardNumber).toBe(
|
|
269
|
-
'4111script1111/script1111'
|
|
270
|
-
)
|
|
271
|
-
expect(result.payments[0].creditCard.cvv).toBe('123')
|
|
272
|
-
expect(result.payments[0].creditCard.month).toBe('12')
|
|
273
|
-
expect(result.payments[0].creditCard.year).toBe('2025')
|
|
274
|
-
expect(result.payments[0].creditCard.holderName).toBe(
|
|
275
|
-
'scriptalert("xss")/scriptJohn Doe'
|
|
276
|
-
)
|
|
277
|
-
})
|
|
278
|
-
|
|
279
|
-
test('should sanitize order items', () => {
|
|
280
|
-
const order = {
|
|
281
|
-
items: [
|
|
282
|
-
{
|
|
283
|
-
externalReferenceId: 'ref<script>123</script>',
|
|
284
|
-
description: 'Product<script>description</script>',
|
|
285
|
-
name: 'Product<script>Name</script>',
|
|
286
|
-
quantity: 1,
|
|
287
|
-
priceInCents: 1000,
|
|
288
|
-
},
|
|
289
|
-
],
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const result = sanitizeOrderData(order)
|
|
293
|
-
|
|
294
|
-
expect(result.items[0].externalReferenceId).toBe('refscript123/script')
|
|
295
|
-
expect(result.items[0].description).toBe(
|
|
296
|
-
'Productscriptdescription/script'
|
|
297
|
-
)
|
|
298
|
-
expect(result.items[0].name).toBe('ProductscriptName/script')
|
|
299
|
-
expect(result.items[0].quantity).toBe(1)
|
|
300
|
-
expect(result.items[0].priceInCents).toBe(1000)
|
|
301
|
-
})
|
|
302
|
-
|
|
303
|
-
test('should sanitize metadata', () => {
|
|
304
|
-
const order = {
|
|
305
|
-
metadata: [
|
|
306
|
-
{
|
|
307
|
-
key: 'custom<script>key</script>',
|
|
308
|
-
value: 'custom<script>value</script>',
|
|
309
|
-
},
|
|
310
|
-
],
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
const result = sanitizeOrderData(order)
|
|
314
|
-
|
|
315
|
-
expect(result.metadata[0].key).toBe('customscriptkey/script')
|
|
316
|
-
expect(result.metadata[0].value).toBe('customscriptvalue/script')
|
|
317
|
-
})
|
|
318
|
-
|
|
319
|
-
test('should handle order without buyer information', () => {
|
|
320
|
-
const order = {
|
|
321
|
-
payments: [{ method: 'pix' }],
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
const result = sanitizeOrderData(order)
|
|
325
|
-
|
|
326
|
-
expect(result.buyer).toBeUndefined()
|
|
327
|
-
expect(result.payments).toEqual([{ method: 'pix' }])
|
|
328
|
-
})
|
|
329
|
-
|
|
330
|
-
test('should handle order without payments', () => {
|
|
331
|
-
const order = {
|
|
332
|
-
buyer: { name: 'John Doe' },
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
const result = sanitizeOrderData(order)
|
|
336
|
-
|
|
337
|
-
expect(result.buyer.name).toBe('John Doe')
|
|
338
|
-
expect(result.payments).toBeUndefined()
|
|
339
|
-
})
|
|
340
|
-
|
|
341
|
-
test('should handle order without items', () => {
|
|
342
|
-
const order = {
|
|
343
|
-
buyer: { name: 'John Doe' },
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
const result = sanitizeOrderData(order)
|
|
347
|
-
|
|
348
|
-
expect(result.buyer.name).toBe('John Doe')
|
|
349
|
-
expect(result.items).toBeUndefined()
|
|
350
|
-
})
|
|
351
|
-
|
|
352
|
-
test('should handle order without metadata', () => {
|
|
353
|
-
const order = {
|
|
354
|
-
buyer: { name: 'John Doe' },
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
const result = sanitizeOrderData(order)
|
|
358
|
-
|
|
359
|
-
expect(result.buyer.name).toBe('John Doe')
|
|
360
|
-
expect(result.metadata).toBeUndefined()
|
|
361
|
-
})
|
|
362
|
-
|
|
363
|
-
test('should return deep clone of original order', () => {
|
|
364
|
-
const order = {
|
|
365
|
-
buyer: { name: 'John Doe' },
|
|
366
|
-
payments: [{ method: 'pix' }],
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
const result = sanitizeOrderData(order)
|
|
370
|
-
|
|
371
|
-
expect(result).not.toBe(order)
|
|
372
|
-
expect(result.buyer).not.toBe(order.buyer)
|
|
373
|
-
expect(result.payments).not.toBe(order.payments)
|
|
374
|
-
})
|
|
375
|
-
})
|
|
376
|
-
|
|
377
|
-
describe('sanitizeObjectFields', () => {
|
|
378
|
-
test('should sanitize simple object with string fields', () => {
|
|
379
|
-
const obj = {
|
|
380
|
-
name: '<script>alert("xss")</script>',
|
|
381
|
-
email: 'user@example.com',
|
|
382
|
-
age: 25,
|
|
383
|
-
active: true,
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
const result = Sanitizer.sanitizeObjectFields(obj)
|
|
387
|
-
|
|
388
|
-
expect(result.name).toBe('scriptalert("xss")/script')
|
|
389
|
-
expect(result.email).toBe('user@example.com')
|
|
390
|
-
expect(result.age).toBe(25)
|
|
391
|
-
expect(result.active).toBe(true)
|
|
392
|
-
})
|
|
393
|
-
|
|
394
|
-
test('should sanitize nested objects recursively', () => {
|
|
395
|
-
const obj = {
|
|
396
|
-
user: {
|
|
397
|
-
name: '<script>malicious</script>',
|
|
398
|
-
profile: {
|
|
399
|
-
bio: 'Bio with <strong>HTML</strong>',
|
|
400
|
-
website: 'javascript:alert("xss")',
|
|
401
|
-
},
|
|
402
|
-
},
|
|
403
|
-
settings: {
|
|
404
|
-
theme: 'dark',
|
|
405
|
-
notifications: true,
|
|
406
|
-
},
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
const result = Sanitizer.sanitizeObjectFields(obj)
|
|
410
|
-
|
|
411
|
-
expect(result.user.name).toBe('scriptmalicious/script')
|
|
412
|
-
expect(result.user.profile.bio).toBe('Bio with strongHTML/strong')
|
|
413
|
-
expect(result.user.profile.website).toBe('alert("xss")')
|
|
414
|
-
expect(result.settings.theme).toBe('dark')
|
|
415
|
-
expect(result.settings.notifications).toBe(true)
|
|
416
|
-
})
|
|
417
|
-
|
|
418
|
-
test('should sanitize arrays of objects', () => {
|
|
419
|
-
const obj = {
|
|
420
|
-
users: [
|
|
421
|
-
{
|
|
422
|
-
name: '<script>user1</script>',
|
|
423
|
-
email: 'user1@example.com',
|
|
424
|
-
},
|
|
425
|
-
{
|
|
426
|
-
name: '<script>user2</script>',
|
|
427
|
-
email: 'user2@example.com',
|
|
428
|
-
},
|
|
429
|
-
],
|
|
430
|
-
tags: ['tag1', '<script>malicious</script>', 'tag3'],
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
const result = Sanitizer.sanitizeObjectFields(obj)
|
|
434
|
-
|
|
435
|
-
expect(result.users[0].name).toBe('scriptuser1/script')
|
|
436
|
-
expect(result.users[0].email).toBe('user1@example.com')
|
|
437
|
-
expect(result.users[1].name).toBe('scriptuser2/script')
|
|
438
|
-
expect(result.users[1].email).toBe('user2@example.com')
|
|
439
|
-
expect(result.tags[0]).toBe('tag1')
|
|
440
|
-
expect(result.tags[1]).toBe('scriptmalicious/script')
|
|
441
|
-
expect(result.tags[2]).toBe('tag3')
|
|
442
|
-
})
|
|
443
|
-
|
|
444
|
-
test('should handle primitive values correctly', () => {
|
|
445
|
-
const obj = {
|
|
446
|
-
string: '<script>test</script>',
|
|
447
|
-
number: 42,
|
|
448
|
-
boolean: false,
|
|
449
|
-
nullValue: null,
|
|
450
|
-
undefinedValue: undefined,
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
const result = Sanitizer.sanitizeObjectFields(obj)
|
|
454
|
-
|
|
455
|
-
expect(result.string).toBe('scripttest/script')
|
|
456
|
-
expect(result.number).toBe(42)
|
|
457
|
-
expect(result.boolean).toBe(false)
|
|
458
|
-
expect(result.nullValue).toBe(null)
|
|
459
|
-
expect(result.undefinedValue).toBe(undefined)
|
|
460
|
-
})
|
|
461
|
-
|
|
462
|
-
test('should handle empty objects and arrays', () => {
|
|
463
|
-
const obj = {
|
|
464
|
-
emptyObj: {},
|
|
465
|
-
emptyArray: [],
|
|
466
|
-
nestedEmpty: {
|
|
467
|
-
empty: {},
|
|
468
|
-
array: [],
|
|
469
|
-
},
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
const result = Sanitizer.sanitizeObjectFields(obj)
|
|
473
|
-
|
|
474
|
-
expect(result.emptyObj).toEqual({})
|
|
475
|
-
expect(result.emptyArray).toEqual([])
|
|
476
|
-
expect(result.nestedEmpty.empty).toEqual({})
|
|
477
|
-
expect(result.nestedEmpty.array).toEqual([])
|
|
478
|
-
})
|
|
479
|
-
|
|
480
|
-
test('should handle null and undefined input', () => {
|
|
481
|
-
expect(Sanitizer.sanitizeObjectFields(null)).toBe(null)
|
|
482
|
-
expect(Sanitizer.sanitizeObjectFields(undefined)).toBe(undefined)
|
|
483
|
-
})
|
|
484
|
-
|
|
485
|
-
test('should handle non-object inputs', () => {
|
|
486
|
-
expect(
|
|
487
|
-
Sanitizer.sanitizeObjectFields('test<script>string</script>')
|
|
488
|
-
).toBe('testscriptstring/script')
|
|
489
|
-
expect(Sanitizer.sanitizeObjectFields(123)).toBe(123)
|
|
490
|
-
expect(Sanitizer.sanitizeObjectFields(true)).toBe(true)
|
|
491
|
-
expect(Sanitizer.sanitizeObjectFields('')).toBe('')
|
|
492
|
-
})
|
|
493
|
-
|
|
494
|
-
test('should preserve object structure', () => {
|
|
495
|
-
const obj = {
|
|
496
|
-
level1: {
|
|
497
|
-
level2: {
|
|
498
|
-
level3: {
|
|
499
|
-
value: '<script>deep</script>',
|
|
500
|
-
},
|
|
501
|
-
},
|
|
502
|
-
},
|
|
503
|
-
array: [
|
|
504
|
-
{
|
|
505
|
-
nested: {
|
|
506
|
-
value: '<script>nested</script>',
|
|
507
|
-
},
|
|
508
|
-
},
|
|
509
|
-
],
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
const result = Sanitizer.sanitizeObjectFields(obj)
|
|
513
|
-
|
|
514
|
-
// Verify structure is preserved
|
|
515
|
-
expect(result.level1).toBeDefined()
|
|
516
|
-
expect(result.level1.level2).toBeDefined()
|
|
517
|
-
expect(result.level1.level2.level3).toBeDefined()
|
|
518
|
-
expect(result.array).toBeDefined()
|
|
519
|
-
expect(result.array[0]).toBeDefined()
|
|
520
|
-
expect(result.array[0].nested).toBeDefined()
|
|
521
|
-
|
|
522
|
-
// Verify values are sanitized
|
|
523
|
-
expect(result.level1.level2.level3.value).toBe('scriptdeep/script')
|
|
524
|
-
expect(result.array[0].nested.value).toBe('scriptnested/script')
|
|
525
|
-
})
|
|
526
|
-
|
|
527
|
-
test('should handle circular references gracefully', () => {
|
|
528
|
-
const obj = { name: '<script>test</script>' }
|
|
529
|
-
obj.self = obj
|
|
530
|
-
|
|
531
|
-
// This should not cause infinite recursion
|
|
532
|
-
const result = Sanitizer.sanitizeObjectFields(obj)
|
|
533
|
-
|
|
534
|
-
expect(result.name).toBe('scripttest/script')
|
|
535
|
-
expect(result.self).toBeDefined()
|
|
536
|
-
})
|
|
537
|
-
|
|
538
|
-
test('should sanitize complex nested structures', () => {
|
|
539
|
-
const obj = {
|
|
540
|
-
company: {
|
|
541
|
-
name: 'Company<script>Name</script>',
|
|
542
|
-
departments: [
|
|
543
|
-
{
|
|
544
|
-
name: 'IT<script>Dept</script>',
|
|
545
|
-
employees: [
|
|
546
|
-
{
|
|
547
|
-
name: 'John<script>Doe</script>',
|
|
548
|
-
skills: [
|
|
549
|
-
'JavaScript',
|
|
550
|
-
'<script>malicious</script>',
|
|
551
|
-
'React',
|
|
552
|
-
],
|
|
553
|
-
},
|
|
554
|
-
],
|
|
555
|
-
},
|
|
556
|
-
],
|
|
557
|
-
settings: {
|
|
558
|
-
theme: 'light<script>theme</script>',
|
|
559
|
-
features: {
|
|
560
|
-
enabled: true,
|
|
561
|
-
name: 'Feature<script>Name</script>',
|
|
562
|
-
},
|
|
563
|
-
},
|
|
564
|
-
},
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
const result = Sanitizer.sanitizeObjectFields(obj)
|
|
568
|
-
|
|
569
|
-
// Verify complex structure is sanitized
|
|
570
|
-
expect(result.company.name).toBe('CompanyscriptName/script')
|
|
571
|
-
expect(result.company.departments[0].name).toBe('ITscriptDept/script')
|
|
572
|
-
expect(result.company.departments[0].employees[0].name).toBe(
|
|
573
|
-
'JohnscriptDoe/script'
|
|
574
|
-
)
|
|
575
|
-
expect(result.company.departments[0].employees[0].skills[1]).toBe(
|
|
576
|
-
'scriptmalicious/script'
|
|
577
|
-
)
|
|
578
|
-
expect(result.company.settings.theme).toBe('lightscripttheme/script')
|
|
579
|
-
expect(result.company.settings.features.name).toBe(
|
|
580
|
-
'FeaturescriptName/script'
|
|
581
|
-
)
|
|
582
|
-
})
|
|
583
|
-
})
|