avo-inspector 3.2.0 → 3.2.3
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 +10 -0
- package/dist/AvoBatcher.d.ts +9 -3
- package/dist/AvoInspector.d.ts +4 -0
- package/dist/AvoNetworkCallsHandler.d.ts +80 -5
- package/dist/__tests__/UnboundPublicMethods_test.d.ts +1 -0
- package/dist/__tests__/constants.d.ts +2 -1
- package/dist/__tests__/helpers/internalGateway.d.ts +23 -0
- package/dist/eventSpec/AvoEventSpecCache.d.ts +7 -4
- package/dist/eventSpec/AvoEventSpecFetchTypes.d.ts +12 -1
- package/dist/eventSpec/AvoEventSpecFetcher.d.ts +6 -1
- package/dist/index.js +1 -1
- package/dist/lite/AvoBatcherLite.d.ts +9 -3
- package/dist/lite/AvoBatcherLite.js +46 -7
- package/dist/lite/AvoInspectorLite.d.ts +2 -0
- package/dist/lite/AvoInspectorLite.js +95 -15
- package/dist/lite/AvoNetworkCallsHandlerLite.d.ts +79 -5
- package/dist/lite/AvoNetworkCallsHandlerLite.js +300 -20
- package/package.json +10 -1
- package/dist/AvoBatcher.js +0 -87
- package/dist/AvoDeduplicator.js +0 -142
- package/dist/AvoEncryption.js +0 -176
- package/dist/AvoInspector.js +0 -435
- package/dist/AvoNetworkCallsHandler.js +0 -229
- package/dist/AvoSchemaParser.js +0 -95
- package/dist/AvoStreamId.js +0 -82
- package/dist/__mocks__/xhr.js +0 -14
- package/dist/__mocks__/xhrError.js +0 -14
- package/dist/__tests__/AvoEncryption.js +0 -272
- package/dist/__tests__/AvoEncryptionIntegration.js +0 -191
- package/dist/__tests__/AvoEventSpecFetcher.js +0 -377
- package/dist/__tests__/AvoInspector.js +0 -335
- package/dist/__tests__/Batcher.js +0 -214
- package/dist/__tests__/BatcherPublic.js +0 -139
- package/dist/__tests__/Deduplicator.js +0 -190
- package/dist/__tests__/EventSpecCache.js +0 -143
- package/dist/__tests__/EventValidator.js +0 -543
- package/dist/__tests__/InstallationId.js +0 -60
- package/dist/__tests__/NetworkCallsHandler.js +0 -222
- package/dist/__tests__/NetworkCallsHandlerModelA.js +0 -206
- package/dist/__tests__/Parsing.js +0 -115
- package/dist/__tests__/Sessions.d.ts +0 -1
- package/dist/__tests__/Sessions.js +0 -10
- package/dist/__tests__/Storage.d.ts +0 -1
- package/dist/__tests__/Storage.js +0 -173
- package/dist/__tests__/StreamId.d.ts +0 -1
- package/dist/__tests__/StreamId.js +0 -153
- package/dist/__tests__/constants.js +0 -48
- package/dist/esm/AvoBatcher.js +0 -75
- package/dist/esm/AvoDeduplicator.js +0 -137
- package/dist/esm/AvoEncryption.js +0 -277
- package/dist/esm/AvoGuid.js +0 -9
- package/dist/esm/AvoInspector.js +0 -470
- package/dist/esm/AvoInspectorEnv.js +0 -5
- package/dist/esm/AvoNetworkCallsHandler.js +0 -181
- package/dist/esm/AvoSchemaParser.js +0 -128
- package/dist/esm/AvoStorage.js +0 -176
- package/dist/esm/AvoStreamId.js +0 -140
- package/dist/esm/eventSpec/AvoEventSpecCache.js +0 -165
- package/dist/esm/eventSpec/AvoEventSpecFetchTypes.js +0 -6
- package/dist/esm/eventSpec/AvoEventSpecFetcher.js +0 -203
- package/dist/esm/eventSpec/EventValidator.js +0 -687
- package/dist/esm/eventSpec/index.js +0 -4
- package/dist/esm/index.js +0 -3
- package/dist/esm/utils.js +0 -38
- package/dist/esm/version.js +0 -2
- package/dist/eventSpec/AvoEventSpecCache.js +0 -181
- package/dist/eventSpec/AvoEventSpecFetcher.js +0 -290
- package/dist/eventSpec/EventValidator.js +0 -846
- package/dist/eventSpec/index.js +0 -20
- package/dist/version.d.ts +0 -1
- package/dist/version.js +0 -5
- /package/dist/__tests__/{AvoEncryption.d.ts → ApiKeyHeaderInjection_test.d.ts} +0 -0
- /package/dist/__tests__/{AvoEncryptionIntegration.d.ts → BrowserBootstrap_test.d.ts} +0 -0
- /package/dist/__tests__/{AvoEventSpecFetcher.d.ts → EventSpecGatewayCoordinates_test.d.ts} +0 -0
- /package/dist/__tests__/{AvoInspector.d.ts → InFlightQueueGaps_test.d.ts} +0 -0
- /package/dist/__tests__/{Batcher.d.ts → InFlightQueue_test.d.ts} +0 -0
- /package/dist/__tests__/{BatcherPublic.d.ts → NetworkCallsHandlerLite_test.d.ts} +0 -0
- /package/dist/__tests__/{Deduplicator.d.ts → PublicSurface_test.d.ts} +0 -0
- /package/dist/__tests__/{EventSpecCache.d.ts → TrackOptionsIntegration_test.d.ts} +0 -0
- /package/dist/__tests__/{EventValidator.d.ts → TrackOptionsTransport_test.d.ts} +0 -0
- /package/dist/__tests__/{InstallationId.d.ts → TrackingHeaders_test.d.ts} +0 -0
- /package/dist/__tests__/{NetworkCallsHandler.d.ts → V1WireBaseline_test.d.ts} +0 -0
- /package/dist/__tests__/{NetworkCallsHandlerModelA.d.ts → V2QueuedAttribution_test.d.ts} +0 -0
- /package/dist/__tests__/{Parsing.d.ts → V2StopSending_test.d.ts} +0 -0
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
/**
|
|
4
|
-
* Tests for AvoEncryption (React Native - @noble/ciphers based, fully synchronous).
|
|
5
|
-
*
|
|
6
|
-
* Covers:
|
|
7
|
-
* - shouldEncrypt() truth table
|
|
8
|
-
* - Wire format structural tests
|
|
9
|
-
* - Cross-SDK interop (TypeScript mirror of Java EncryptionInteropTestUtil)
|
|
10
|
-
* - Encryption failure handling
|
|
11
|
-
* - List-type property omission
|
|
12
|
-
* - publicEncryptionKey in base body
|
|
13
|
-
* - Prod negative test
|
|
14
|
-
*/
|
|
15
|
-
var p256_1 = require("@noble/curves/p256");
|
|
16
|
-
var aes_1 = require("@noble/ciphers/aes");
|
|
17
|
-
var sha256_1 = require("@noble/hashes/sha256");
|
|
18
|
-
var AvoEncryption_1 = require("../AvoEncryption");
|
|
19
|
-
// =========================================================================
|
|
20
|
-
// Helper: TypeScript mirror of Java EncryptionInteropTestUtil.decrypt
|
|
21
|
-
// =========================================================================
|
|
22
|
-
function hexToBytes(hex) {
|
|
23
|
-
var bytes = new Uint8Array(hex.length / 2);
|
|
24
|
-
for (var i = 0; i < hex.length; i += 2) {
|
|
25
|
-
bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
|
|
26
|
-
}
|
|
27
|
-
return bytes;
|
|
28
|
-
}
|
|
29
|
-
function bytesToHex(bytes) {
|
|
30
|
-
return Array.from(bytes)
|
|
31
|
-
.map(function (b) { return b.toString(16).padStart(2, "0"); })
|
|
32
|
-
.join("");
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Reference decryptor mirroring Java EncryptionInteropTestUtil.decrypt.
|
|
36
|
-
* Uses @noble/curves + @noble/ciphers (same libs, but acts as independent verification).
|
|
37
|
-
*/
|
|
38
|
-
function referenceDecrypt(base64Encrypted, privateKeyHex) {
|
|
39
|
-
var data = Buffer.from(base64Encrypted, "base64");
|
|
40
|
-
// Minimum length: 1 (version) + 65 (ephemeral pub key) + 16 (IV) + 16 (auth tag) + 1 (min ciphertext)
|
|
41
|
-
if (data.length < 99) {
|
|
42
|
-
throw new Error("Encrypted data too short: expected at least 99 bytes, got ".concat(data.length));
|
|
43
|
-
}
|
|
44
|
-
// Step 2: Assert version byte
|
|
45
|
-
if (data[0] !== 0x00) {
|
|
46
|
-
throw new Error("Unsupported version byte: expected 0x00, got 0x".concat(data[0].toString(16).padStart(2, "0")));
|
|
47
|
-
}
|
|
48
|
-
// Step 3: Extract ephemeral public key bytes [1..65] (65 bytes, uncompressed EC point)
|
|
49
|
-
var ephemeralPubKeyBytes = new Uint8Array(data.slice(1, 66));
|
|
50
|
-
// Step 4: Extract IV [66..81] (16 bytes)
|
|
51
|
-
var iv = new Uint8Array(data.slice(66, 82));
|
|
52
|
-
// Step 5: Extract auth tag [82..97] (16 bytes)
|
|
53
|
-
var authTag = new Uint8Array(data.slice(82, 98));
|
|
54
|
-
// Step 6: Extract ciphertext [98..N]
|
|
55
|
-
var ciphertext = new Uint8Array(data.slice(98));
|
|
56
|
-
// Step 7-8: ECDH with recipient private key -> sharedSecret
|
|
57
|
-
var privateKeyBytes = hexToBytes(privateKeyHex);
|
|
58
|
-
var sharedSecretPoint = p256_1.p256.getSharedSecret(privateKeyBytes, ephemeralPubKeyBytes);
|
|
59
|
-
var sharedSecret = sharedSecretPoint.slice(-32); // X-coordinate
|
|
60
|
-
// Step 9: KDF: SHA-256(sharedSecret) -> aesKey
|
|
61
|
-
var aesKey = (0, sha256_1.sha256)(sharedSecret);
|
|
62
|
-
// Step 10: AES/GCM decrypt
|
|
63
|
-
// @noble/ciphers gcm expects ciphertext + authTag concatenated
|
|
64
|
-
var ciphertextWithTag = new Uint8Array(ciphertext.length + authTag.length);
|
|
65
|
-
ciphertextWithTag.set(ciphertext, 0);
|
|
66
|
-
ciphertextWithTag.set(authTag, ciphertext.length);
|
|
67
|
-
var aes = (0, aes_1.gcm)(aesKey, iv);
|
|
68
|
-
var plainBytes = aes.decrypt(ciphertextWithTag);
|
|
69
|
-
// Step 11: Return as UTF-8 string
|
|
70
|
-
return new TextDecoder().decode(plainBytes);
|
|
71
|
-
}
|
|
72
|
-
// =========================================================================
|
|
73
|
-
// Generate a test key pair
|
|
74
|
-
// =========================================================================
|
|
75
|
-
function generateTestKeyPair() {
|
|
76
|
-
var privateKeyBytes = p256_1.p256.utils.randomPrivateKey();
|
|
77
|
-
var publicKeyBytes = p256_1.p256.getPublicKey(privateKeyBytes, false);
|
|
78
|
-
return {
|
|
79
|
-
privateKey: bytesToHex(privateKeyBytes).padStart(64, "0"),
|
|
80
|
-
publicKey: bytesToHex(publicKeyBytes),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
// =========================================================================
|
|
84
|
-
// Tests
|
|
85
|
-
// =========================================================================
|
|
86
|
-
describe("AvoEncryption (React Native - @noble/ciphers)", function () {
|
|
87
|
-
// -----------------------------------------------------------------------
|
|
88
|
-
// shouldEncrypt() truth table
|
|
89
|
-
// -----------------------------------------------------------------------
|
|
90
|
-
describe("shouldEncrypt()", function () {
|
|
91
|
-
test("dev + valid key = true", function () {
|
|
92
|
-
expect((0, AvoEncryption_1.shouldEncrypt)("dev", "04abcdef1234")).toBe(true);
|
|
93
|
-
});
|
|
94
|
-
test("staging + valid key = true", function () {
|
|
95
|
-
expect((0, AvoEncryption_1.shouldEncrypt)("staging", "04abcdef1234")).toBe(true);
|
|
96
|
-
});
|
|
97
|
-
test("prod + valid key = false", function () {
|
|
98
|
-
expect((0, AvoEncryption_1.shouldEncrypt)("prod", "04abcdef1234")).toBe(false);
|
|
99
|
-
});
|
|
100
|
-
test("dev + null key = false", function () {
|
|
101
|
-
expect((0, AvoEncryption_1.shouldEncrypt)("dev", null)).toBe(false);
|
|
102
|
-
});
|
|
103
|
-
test("dev + undefined key = false", function () {
|
|
104
|
-
expect((0, AvoEncryption_1.shouldEncrypt)("dev", undefined)).toBe(false);
|
|
105
|
-
});
|
|
106
|
-
test("dev + empty string key = false", function () {
|
|
107
|
-
expect((0, AvoEncryption_1.shouldEncrypt)("dev", "")).toBe(false);
|
|
108
|
-
});
|
|
109
|
-
test("dev + whitespace-only key = false", function () {
|
|
110
|
-
expect((0, AvoEncryption_1.shouldEncrypt)("dev", " ")).toBe(false);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
// -----------------------------------------------------------------------
|
|
114
|
-
// Wire format structural test
|
|
115
|
-
// -----------------------------------------------------------------------
|
|
116
|
-
describe("Wire format", function () {
|
|
117
|
-
var keyPair = generateTestKeyPair();
|
|
118
|
-
test("base64Decode(output).length >= 99", function () {
|
|
119
|
-
var encrypted = (0, AvoEncryption_1.encryptValue)("hello world", keyPair.publicKey);
|
|
120
|
-
var decoded = Buffer.from(encrypted, "base64");
|
|
121
|
-
expect(decoded.length).toBeGreaterThanOrEqual(99);
|
|
122
|
-
});
|
|
123
|
-
test("output[0] == 0x00 (version byte)", function () {
|
|
124
|
-
var encrypted = (0, AvoEncryption_1.encryptValue)("hello world", keyPair.publicKey);
|
|
125
|
-
var decoded = Buffer.from(encrypted, "base64");
|
|
126
|
-
expect(decoded[0]).toBe(0x00);
|
|
127
|
-
});
|
|
128
|
-
test("output[1] == 0x04 (uncompressed point marker)", function () {
|
|
129
|
-
var encrypted = (0, AvoEncryption_1.encryptValue)("hello world", keyPair.publicKey);
|
|
130
|
-
var decoded = Buffer.from(encrypted, "base64");
|
|
131
|
-
expect(decoded[1]).toBe(0x04);
|
|
132
|
-
});
|
|
133
|
-
test("encryptValue is synchronous (returns string, not Promise)", function () {
|
|
134
|
-
var result = (0, AvoEncryption_1.encryptValue)("test", keyPair.publicKey);
|
|
135
|
-
// If it were async, result would be a Promise, not a string
|
|
136
|
-
expect(typeof result).toBe("string");
|
|
137
|
-
// Ensure it's NOT a Promise
|
|
138
|
-
expect(result).not.toBeInstanceOf(Promise);
|
|
139
|
-
});
|
|
140
|
-
test("different encryptions produce different output", function () {
|
|
141
|
-
var enc1 = (0, AvoEncryption_1.encryptValue)("same", keyPair.publicKey);
|
|
142
|
-
var enc2 = (0, AvoEncryption_1.encryptValue)("same", keyPair.publicKey);
|
|
143
|
-
expect(enc1).not.toBe(enc2);
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
// -----------------------------------------------------------------------
|
|
147
|
-
// Cross-SDK interop: RN-encrypted ciphertext decryptable by reference decryptor
|
|
148
|
-
// -----------------------------------------------------------------------
|
|
149
|
-
describe("Cross-SDK interop", function () {
|
|
150
|
-
var keyPair = generateTestKeyPair();
|
|
151
|
-
var standardPlaintexts = [
|
|
152
|
-
'"hello world"',
|
|
153
|
-
"42",
|
|
154
|
-
"3.14",
|
|
155
|
-
"true",
|
|
156
|
-
'"test string value"',
|
|
157
|
-
];
|
|
158
|
-
standardPlaintexts.forEach(function (plaintext) {
|
|
159
|
-
test("RN encrypt -> reference decrypt: ".concat(plaintext), function () {
|
|
160
|
-
var encrypted = (0, AvoEncryption_1.encryptValue)(plaintext, keyPair.publicKey);
|
|
161
|
-
var decrypted = referenceDecrypt(encrypted, keyPair.privateKey);
|
|
162
|
-
expect(decrypted).toBe(plaintext);
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
test("round-trip with JSON-stringified object", function () {
|
|
166
|
-
var obj = { key: "value", number: 123 };
|
|
167
|
-
var jsonStr = JSON.stringify(obj);
|
|
168
|
-
var encrypted = (0, AvoEncryption_1.encryptValue)(jsonStr, keyPair.publicKey);
|
|
169
|
-
var decrypted = referenceDecrypt(encrypted, keyPair.privateKey);
|
|
170
|
-
expect(decrypted).toBe(jsonStr);
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
// -----------------------------------------------------------------------
|
|
174
|
-
// encryptEventProperties
|
|
175
|
-
// -----------------------------------------------------------------------
|
|
176
|
-
describe("encryptEventProperties()", function () {
|
|
177
|
-
var keyPair = generateTestKeyPair();
|
|
178
|
-
test("encrypts string property values", function () {
|
|
179
|
-
var properties = [
|
|
180
|
-
{ propertyName: "name", propertyType: "string" },
|
|
181
|
-
];
|
|
182
|
-
var eventProps = { name: "Alice" };
|
|
183
|
-
var result = (0, AvoEncryption_1.encryptEventProperties)(properties, eventProps, keyPair.publicKey);
|
|
184
|
-
expect(result).toHaveLength(1);
|
|
185
|
-
expect(result[0].propertyName).toBe("name");
|
|
186
|
-
expect(result[0].propertyType).toBe("string");
|
|
187
|
-
expect(result[0].encryptedPropertyValue).toBeDefined();
|
|
188
|
-
// Verify it decrypts correctly
|
|
189
|
-
var decrypted = referenceDecrypt(result[0].encryptedPropertyValue, keyPair.privateKey);
|
|
190
|
-
expect(JSON.parse(decrypted)).toBe("Alice");
|
|
191
|
-
});
|
|
192
|
-
test("encrypts int property values", function () {
|
|
193
|
-
var properties = [
|
|
194
|
-
{ propertyName: "age", propertyType: "int" },
|
|
195
|
-
];
|
|
196
|
-
var eventProps = { age: 42 };
|
|
197
|
-
var result = (0, AvoEncryption_1.encryptEventProperties)(properties, eventProps, keyPair.publicKey);
|
|
198
|
-
expect(result[0].encryptedPropertyValue).toBeDefined();
|
|
199
|
-
var decrypted = referenceDecrypt(result[0].encryptedPropertyValue, keyPair.privateKey);
|
|
200
|
-
expect(JSON.parse(decrypted)).toBe(42);
|
|
201
|
-
});
|
|
202
|
-
test("encrypts boolean property values", function () {
|
|
203
|
-
var properties = [
|
|
204
|
-
{ propertyName: "active", propertyType: "boolean" },
|
|
205
|
-
];
|
|
206
|
-
var eventProps = { active: true };
|
|
207
|
-
var result = (0, AvoEncryption_1.encryptEventProperties)(properties, eventProps, keyPair.publicKey);
|
|
208
|
-
expect(result[0].encryptedPropertyValue).toBeDefined();
|
|
209
|
-
var decrypted = referenceDecrypt(result[0].encryptedPropertyValue, keyPair.privateKey);
|
|
210
|
-
expect(JSON.parse(decrypted)).toBe(true);
|
|
211
|
-
});
|
|
212
|
-
test("omits list-type properties entirely", function () {
|
|
213
|
-
var properties = [
|
|
214
|
-
{ propertyName: "tags", propertyType: "list", children: ["string"] },
|
|
215
|
-
{ propertyName: "name", propertyType: "string" },
|
|
216
|
-
];
|
|
217
|
-
var eventProps = { tags: ["a", "b"], name: "Alice" };
|
|
218
|
-
var result = (0, AvoEncryption_1.encryptEventProperties)(properties, eventProps, keyPair.publicKey);
|
|
219
|
-
// list property should be omitted entirely
|
|
220
|
-
expect(result).toHaveLength(1);
|
|
221
|
-
expect(result[0].propertyName).toBe("name");
|
|
222
|
-
});
|
|
223
|
-
test("encryption failure: console.warn, omit property, continue", function () {
|
|
224
|
-
var warnSpy = jest.spyOn(console, "warn").mockImplementation();
|
|
225
|
-
var properties = [
|
|
226
|
-
{ propertyName: "secret", propertyType: "string" },
|
|
227
|
-
{ propertyName: "name", propertyType: "string" },
|
|
228
|
-
];
|
|
229
|
-
var eventProps = { secret: "value1", name: "value2" };
|
|
230
|
-
// Use an invalid public key to trigger encryption failure for the first property
|
|
231
|
-
// We can't easily make only one fail, so let's test with a completely invalid key
|
|
232
|
-
var result = (0, AvoEncryption_1.encryptEventProperties)(properties, eventProps, "invalid-key");
|
|
233
|
-
// Both should fail with invalid key, so both should be omitted
|
|
234
|
-
expect(result).toHaveLength(0);
|
|
235
|
-
expect(warnSpy).toHaveBeenCalledTimes(1);
|
|
236
|
-
// Check that warning message matches expected format
|
|
237
|
-
var calls = warnSpy.mock.calls;
|
|
238
|
-
expect(calls.some(function (call) {
|
|
239
|
-
return String(call[0]).includes("[Avo Inspector] Encryption failed:");
|
|
240
|
-
})).toBe(true);
|
|
241
|
-
warnSpy.mockRestore();
|
|
242
|
-
});
|
|
243
|
-
test("null property values are encrypted as null", function () {
|
|
244
|
-
var properties = [
|
|
245
|
-
{ propertyName: "nullProp", propertyType: "null" },
|
|
246
|
-
];
|
|
247
|
-
var eventProps = { nullProp: null };
|
|
248
|
-
var result = (0, AvoEncryption_1.encryptEventProperties)(properties, eventProps, keyPair.publicKey);
|
|
249
|
-
expect(result).toHaveLength(1);
|
|
250
|
-
expect(result[0].encryptedPropertyValue).toBeDefined();
|
|
251
|
-
var decrypted = referenceDecrypt(result[0].encryptedPropertyValue, keyPair.privateKey);
|
|
252
|
-
expect(JSON.parse(decrypted)).toBeNull();
|
|
253
|
-
});
|
|
254
|
-
test("object property values are encrypted", function () {
|
|
255
|
-
var properties = [
|
|
256
|
-
{
|
|
257
|
-
propertyName: "address",
|
|
258
|
-
propertyType: "object",
|
|
259
|
-
children: [
|
|
260
|
-
{ propertyName: "street", propertyType: "string" },
|
|
261
|
-
],
|
|
262
|
-
},
|
|
263
|
-
];
|
|
264
|
-
var eventProps = { address: { street: "123 Main St" } };
|
|
265
|
-
var result = (0, AvoEncryption_1.encryptEventProperties)(properties, eventProps, keyPair.publicKey);
|
|
266
|
-
expect(result).toHaveLength(1);
|
|
267
|
-
expect(result[0].encryptedPropertyValue).toBeDefined();
|
|
268
|
-
var decrypted = referenceDecrypt(result[0].encryptedPropertyValue, keyPair.privateKey);
|
|
269
|
-
expect(JSON.parse(decrypted)).toEqual({ street: "123 Main St" });
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
});
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
/**
|
|
40
|
-
* Integration tests for encryption in AvoNetworkCallsHandler.
|
|
41
|
-
*
|
|
42
|
-
* Covers:
|
|
43
|
-
* - publicEncryptionKey in base body when non-null and non-empty
|
|
44
|
-
* - Prod negative test: no encryptedPropertyValue in prod env payload
|
|
45
|
-
* - Dev positive test: encryptedPropertyValue present in dev env payload
|
|
46
|
-
*/
|
|
47
|
-
var AvoGuid_1 = require("../AvoGuid");
|
|
48
|
-
var AvoStreamId_1 = require("../AvoStreamId");
|
|
49
|
-
var AvoNetworkCallsHandler_1 = require("../AvoNetworkCallsHandler");
|
|
50
|
-
var p256_1 = require("@noble/curves/p256");
|
|
51
|
-
var constants_1 = require("./constants");
|
|
52
|
-
function bytesToHex(bytes) {
|
|
53
|
-
return Array.from(bytes)
|
|
54
|
-
.map(function (b) { return b.toString(16).padStart(2, "0"); })
|
|
55
|
-
.join("");
|
|
56
|
-
}
|
|
57
|
-
function generateTestKeyPair() {
|
|
58
|
-
var privateKeyBytes = p256_1.p256.utils.randomPrivateKey();
|
|
59
|
-
var publicKeyBytes = p256_1.p256.getPublicKey(privateKeyBytes, false);
|
|
60
|
-
return {
|
|
61
|
-
privateKey: bytesToHex(privateKeyBytes).padStart(64, "0"),
|
|
62
|
-
publicKey: bytesToHex(publicKeyBytes),
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
var keyPair = generateTestKeyPair();
|
|
66
|
-
describe("AvoNetworkCallsHandler encryption integration", function () {
|
|
67
|
-
var now = new Date();
|
|
68
|
-
beforeAll(function () {
|
|
69
|
-
// @ts-ignore
|
|
70
|
-
jest.spyOn(global, "Date").mockImplementation(function () { return now; });
|
|
71
|
-
jest
|
|
72
|
-
.spyOn(AvoStreamId_1.AvoStreamId, "initialize")
|
|
73
|
-
.mockResolvedValue(constants_1.mockedReturns.ANONYMOUS_ID);
|
|
74
|
-
jest
|
|
75
|
-
.spyOn(AvoGuid_1.default, "newGuid")
|
|
76
|
-
.mockImplementation(function () { return constants_1.mockedReturns.GUID; });
|
|
77
|
-
});
|
|
78
|
-
afterAll(function () {
|
|
79
|
-
jest.restoreAllMocks();
|
|
80
|
-
});
|
|
81
|
-
test("publicEncryptionKey is included in base body when non-null and non-empty", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
82
|
-
var handler, body;
|
|
83
|
-
return __generator(this, function (_a) {
|
|
84
|
-
switch (_a.label) {
|
|
85
|
-
case 0:
|
|
86
|
-
handler = new AvoNetworkCallsHandler_1.AvoNetworkCallsHandler("test-api-key", "dev", "TestApp", "1.0.0", "1.0.0", keyPair.publicKey);
|
|
87
|
-
return [4 /*yield*/, handler.bodyForEventSchemaCall("testEvent", [{ propertyName: "name", propertyType: "string" }], null, null, { name: "Alice" })];
|
|
88
|
-
case 1:
|
|
89
|
-
body = _a.sent();
|
|
90
|
-
expect(body.publicEncryptionKey).toBe(keyPair.publicKey);
|
|
91
|
-
return [2 /*return*/];
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
}); });
|
|
95
|
-
test("publicEncryptionKey is NOT included in base body when null", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
96
|
-
var handler, body;
|
|
97
|
-
return __generator(this, function (_a) {
|
|
98
|
-
switch (_a.label) {
|
|
99
|
-
case 0:
|
|
100
|
-
handler = new AvoNetworkCallsHandler_1.AvoNetworkCallsHandler("test-api-key", "dev", "TestApp", "1.0.0", "1.0.0");
|
|
101
|
-
return [4 /*yield*/, handler.bodyForEventSchemaCall("testEvent", [{ propertyName: "name", propertyType: "string" }], null, null)];
|
|
102
|
-
case 1:
|
|
103
|
-
body = _a.sent();
|
|
104
|
-
expect(body.publicEncryptionKey).toBeUndefined();
|
|
105
|
-
return [2 /*return*/];
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
}); });
|
|
109
|
-
test("publicEncryptionKey is NOT included in base body when empty string", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
110
|
-
var handler, body;
|
|
111
|
-
return __generator(this, function (_a) {
|
|
112
|
-
switch (_a.label) {
|
|
113
|
-
case 0:
|
|
114
|
-
handler = new AvoNetworkCallsHandler_1.AvoNetworkCallsHandler("test-api-key", "dev", "TestApp", "1.0.0", "1.0.0", "");
|
|
115
|
-
return [4 /*yield*/, handler.bodyForEventSchemaCall("testEvent", [{ propertyName: "name", propertyType: "string" }], null, null)];
|
|
116
|
-
case 1:
|
|
117
|
-
body = _a.sent();
|
|
118
|
-
expect(body.publicEncryptionKey).toBeUndefined();
|
|
119
|
-
return [2 /*return*/];
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
}); });
|
|
123
|
-
test("Prod negative test: no encryptedPropertyValue in prod env payload", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
124
|
-
var handler, body, _i, _a, prop;
|
|
125
|
-
return __generator(this, function (_b) {
|
|
126
|
-
switch (_b.label) {
|
|
127
|
-
case 0:
|
|
128
|
-
handler = new AvoNetworkCallsHandler_1.AvoNetworkCallsHandler("test-api-key", "prod", "TestApp", "1.0.0", "1.0.0", keyPair.publicKey);
|
|
129
|
-
return [4 /*yield*/, handler.bodyForEventSchemaCall("testEvent", [{ propertyName: "name", propertyType: "string" }], null, null, { name: "Alice" })];
|
|
130
|
-
case 1:
|
|
131
|
-
body = _b.sent();
|
|
132
|
-
// In prod, shouldEncrypt returns false, so no encryption
|
|
133
|
-
for (_i = 0, _a = body.eventProperties; _i < _a.length; _i++) {
|
|
134
|
-
prop = _a[_i];
|
|
135
|
-
expect(prop.encryptedPropertyValue).toBeUndefined();
|
|
136
|
-
}
|
|
137
|
-
return [2 /*return*/];
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
}); });
|
|
141
|
-
test("Dev positive test: encryptedPropertyValue present in dev env payload", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
142
|
-
var handler, body;
|
|
143
|
-
return __generator(this, function (_a) {
|
|
144
|
-
switch (_a.label) {
|
|
145
|
-
case 0:
|
|
146
|
-
handler = new AvoNetworkCallsHandler_1.AvoNetworkCallsHandler("test-api-key", "dev", "TestApp", "1.0.0", "1.0.0", keyPair.publicKey);
|
|
147
|
-
return [4 /*yield*/, handler.bodyForEventSchemaCall("testEvent", [{ propertyName: "name", propertyType: "string" }], null, null, { name: "Alice" })];
|
|
148
|
-
case 1:
|
|
149
|
-
body = _a.sent();
|
|
150
|
-
expect(body.eventProperties).toHaveLength(1);
|
|
151
|
-
expect(body.eventProperties[0].encryptedPropertyValue).toBeDefined();
|
|
152
|
-
expect(typeof body.eventProperties[0].encryptedPropertyValue).toBe("string");
|
|
153
|
-
return [2 /*return*/];
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
}); });
|
|
157
|
-
test("Staging positive test: encryptedPropertyValue present in staging env payload", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
158
|
-
var handler, body;
|
|
159
|
-
return __generator(this, function (_a) {
|
|
160
|
-
switch (_a.label) {
|
|
161
|
-
case 0:
|
|
162
|
-
handler = new AvoNetworkCallsHandler_1.AvoNetworkCallsHandler("test-api-key", "staging", "TestApp", "1.0.0", "1.0.0", keyPair.publicKey);
|
|
163
|
-
return [4 /*yield*/, handler.bodyForEventSchemaCall("testEvent", [{ propertyName: "price", propertyType: "float" }], null, null, { price: 9.99 })];
|
|
164
|
-
case 1:
|
|
165
|
-
body = _a.sent();
|
|
166
|
-
expect(body.eventProperties).toHaveLength(1);
|
|
167
|
-
expect(body.eventProperties[0].encryptedPropertyValue).toBeDefined();
|
|
168
|
-
return [2 /*return*/];
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
}); });
|
|
172
|
-
test("List-type properties are omitted in encrypted payload", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
173
|
-
var handler, body;
|
|
174
|
-
return __generator(this, function (_a) {
|
|
175
|
-
switch (_a.label) {
|
|
176
|
-
case 0:
|
|
177
|
-
handler = new AvoNetworkCallsHandler_1.AvoNetworkCallsHandler("test-api-key", "dev", "TestApp", "1.0.0", "1.0.0", keyPair.publicKey);
|
|
178
|
-
return [4 /*yield*/, handler.bodyForEventSchemaCall("testEvent", [
|
|
179
|
-
{ propertyName: "tags", propertyType: "list", children: ["string"] },
|
|
180
|
-
{ propertyName: "name", propertyType: "string" },
|
|
181
|
-
], null, null, { tags: ["a", "b"], name: "Alice" })];
|
|
182
|
-
case 1:
|
|
183
|
-
body = _a.sent();
|
|
184
|
-
// list property should be omitted
|
|
185
|
-
expect(body.eventProperties).toHaveLength(1);
|
|
186
|
-
expect(body.eventProperties[0].propertyName).toBe("name");
|
|
187
|
-
return [2 /*return*/];
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
}); });
|
|
191
|
-
});
|