@optimizely-opal/opal-tool-ocp-sdk 1.0.0-OCP-1442.1 โ 1.0.0-OCP-1442.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/README.md +72 -0
- package/dist/function/GlobalToolFunction.js +1 -1
- package/dist/function/GlobalToolFunction.js.map +1 -1
- package/dist/function/ToolFunction.js +1 -1
- package/dist/function/ToolFunction.js.map +1 -1
- package/dist/logging/ToolLogger.d.ts.map +1 -1
- package/dist/logging/ToolLogger.js +29 -3
- package/dist/logging/ToolLogger.js.map +1 -1
- package/dist/logging/ToolLogger.test.js +110 -50
- package/dist/logging/ToolLogger.test.js.map +1 -1
- package/package.json +1 -1
- package/src/function/GlobalToolFunction.ts +1 -1
- package/src/function/ToolFunction.ts +1 -1
- package/src/logging/ToolLogger.test.ts +219 -213
- package/src/logging/ToolLogger.ts +32 -3
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ A TypeScript SDK for building Opal tools in Optimizely Connect Platform. This SD
|
|
|
14
14
|
- ๐ก๏ธ **Authorization Support** - OptiID token tool authorization
|
|
15
15
|
- ๐ **Parameter Validation** - Define and validate tool parameters with types
|
|
16
16
|
- โ
**Automatic Validation** - SDK automatically validates parameters and returns RFC 9457 compliant error responses
|
|
17
|
+
- ๐ **Request/Response Logging** - Comprehensive logging with sensitive data redaction and performance monitoring
|
|
17
18
|
- ๐งช **Comprehensive Testing** - Fully tested with Jest
|
|
18
19
|
|
|
19
20
|
## Installation
|
|
@@ -400,6 +401,77 @@ Key model classes with generic type support:
|
|
|
400
401
|
- `InteractionResult` - Response from interactions
|
|
401
402
|
- `OptiIdAuthData` - OptiID specific authentication data
|
|
402
403
|
|
|
404
|
+
## Request and Response Logging
|
|
405
|
+
|
|
406
|
+
The SDK automatically logs all incoming requests and outgoing responses with comprehensive metadata for debugging and monitoring purposes.
|
|
407
|
+
|
|
408
|
+
### Logging Features
|
|
409
|
+
|
|
410
|
+
- **Automatic Logging** - All requests and responses are logged without additional configuration
|
|
411
|
+
- **Performance Monitoring** - Request duration tracking with millisecond precision
|
|
412
|
+
- **Security-First** - Sensitive data is automatically redacted from logs
|
|
413
|
+
- **Zaius Audience** - Logs are visible only to developers with appropriate access
|
|
414
|
+
- **Structured Data** - Consistent JSON format for easy parsing and analysis
|
|
415
|
+
|
|
416
|
+
### Request Logging
|
|
417
|
+
|
|
418
|
+
Every incoming request is logged with the following information:
|
|
419
|
+
|
|
420
|
+
```json
|
|
421
|
+
{
|
|
422
|
+
"event": "opal_tool_request",
|
|
423
|
+
"path": "/create-task",
|
|
424
|
+
"parameters": {
|
|
425
|
+
"title": "Complete project",
|
|
426
|
+
"priority": "high",
|
|
427
|
+
"api_key": "[REDACTED]"
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Response Logging
|
|
433
|
+
|
|
434
|
+
Every outgoing response is logged with performance and metadata:
|
|
435
|
+
|
|
436
|
+
```json
|
|
437
|
+
{
|
|
438
|
+
"event": "opal_tool_response",
|
|
439
|
+
"path": "/create-task",
|
|
440
|
+
"duration": "150ms",
|
|
441
|
+
"status": 200,
|
|
442
|
+
"contentType": "application/json",
|
|
443
|
+
"contentLength": 234,
|
|
444
|
+
"success": true
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Sensitive Data Redaction
|
|
449
|
+
|
|
450
|
+
The SDK automatically redacts sensitive information from request logs to protect security credentials and personal data. The following field types are automatically redacted:
|
|
451
|
+
|
|
452
|
+
**Authentication & Security:**
|
|
453
|
+
- `password`, `pass`, `secret`, `key`, `token`
|
|
454
|
+
- `auth`, `credentials`, `access_token`, `refresh_token`
|
|
455
|
+
- `api_key`, `private_key`, `client_secret`, `session_token`
|
|
456
|
+
- `authorization`, `bearer_token`, `jwt`
|
|
457
|
+
- `otp`, `pin`, `signing_key`, `encryption_key`
|
|
458
|
+
|
|
459
|
+
**Payment Information:**
|
|
460
|
+
- `card_number`, `credit_card`, `cvv`, `expiry_date`
|
|
461
|
+
|
|
462
|
+
**Personal Data:**
|
|
463
|
+
- `ssn`, `nid`, `passport`, `dob`
|
|
464
|
+
- `email`, `phone`, `address`
|
|
465
|
+
|
|
466
|
+
**Security Questions:**
|
|
467
|
+
- `security_answer`, `security_question`
|
|
468
|
+
|
|
469
|
+
Redacted fields appear as `[REDACTED]` in logs while preserving the overall request structure for debugging.
|
|
470
|
+
|
|
471
|
+
### Log Visibility
|
|
472
|
+
|
|
473
|
+
All logs use Zaius audience visibility, meaning developers only see logs for requests from organizations they have access to, maintaining proper data isolation and security.
|
|
474
|
+
|
|
403
475
|
## Discovery and Ready Endpoints
|
|
404
476
|
|
|
405
477
|
The SDK automatically provides two important endpoints:
|
|
@@ -35,7 +35,7 @@ class GlobalToolFunction extends app_sdk_1.GlobalFunction {
|
|
|
35
35
|
});
|
|
36
36
|
ToolLogger_1.ToolLogger.logRequest(this.request);
|
|
37
37
|
const response = await this.handleRequest();
|
|
38
|
-
ToolLogger_1.ToolLogger.logResponse(this.request, response,
|
|
38
|
+
ToolLogger_1.ToolLogger.logResponse(this.request, response, Date.now() - startTime);
|
|
39
39
|
return response;
|
|
40
40
|
}
|
|
41
41
|
async handleRequest() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GlobalToolFunction.js","sourceRoot":"","sources":["../../src/function/GlobalToolFunction.ts"],"names":[],"mappings":";;;AAAA,+CAA8E;AAC9E,iDAA+E;AAC/E,gDAAkD;AAClD,sDAAmD;AAEnD;;;GAGG;AACH,MAAsB,kBAAmB,SAAQ,wBAAc;IAE7D;;;;;OAKG;IACO,KAAK;QACb,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,OAAO;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,oEAAoE;QACpE,MAAM,QAAQ,GAAG,IAAA,2BAAe,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,UAAU,GAAG,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC;QAEhE,IAAA,yBAAe,EAAC;YACd,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,EAAE;YAChE,UAAU,EAAE,UAAU,IAAI,EAAE;SAC7B,CAAC,CAAC;QAEH,uBAAU,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC5C,uBAAU,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"GlobalToolFunction.js","sourceRoot":"","sources":["../../src/function/GlobalToolFunction.ts"],"names":[],"mappings":";;;AAAA,+CAA8E;AAC9E,iDAA+E;AAC/E,gDAAkD;AAClD,sDAAmD;AAEnD;;;GAGG;AACH,MAAsB,kBAAmB,SAAQ,wBAAc;IAE7D;;;;;OAKG;IACO,KAAK;QACb,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,OAAO;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,oEAAoE;QACpE,MAAM,QAAQ,GAAG,IAAA,2BAAe,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,UAAU,GAAG,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC;QAEhE,IAAA,yBAAe,EAAC;YACd,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,EAAE;YAChE,UAAU,EAAE,UAAU,IAAI,EAAE;SAC7B,CAAC,CAAC;QAEH,uBAAU,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC5C,uBAAU,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;QACvE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE,CAAC;YACrC,OAAO,IAAI,kBAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YACnC,OAAO,IAAI,kBAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,sBAAY,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACzD,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,gBAAgB;QAC5B,OAAO,MAAM,IAAA,qCAAyB,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;CACF;AAzDD,gDAyDC"}
|
|
@@ -29,7 +29,7 @@ class ToolFunction extends app_sdk_1.Function {
|
|
|
29
29
|
(0, app_sdk_1.amendLogContext)({ opalThreadId: this.request.headers.get('x-opal-thread-id') || '' });
|
|
30
30
|
ToolLogger_1.ToolLogger.logRequest(this.request);
|
|
31
31
|
const response = await this.handleRequest();
|
|
32
|
-
ToolLogger_1.ToolLogger.logResponse(this.request, response,
|
|
32
|
+
ToolLogger_1.ToolLogger.logResponse(this.request, response, Date.now() - startTime);
|
|
33
33
|
return response;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolFunction.js","sourceRoot":"","sources":["../../src/function/ToolFunction.ts"],"names":[],"mappings":";;;AAAA,+CAAwE;AACxE,iDAA+D;AAC/D,gDAAkD;AAClD,sDAAmD;AAEnD;;;GAGG;AACH,MAAsB,YAAa,SAAQ,kBAAQ;IAEjD;;;;;OAKG;IACO,KAAK;QACb,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,OAAO;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAA,yBAAe,EAAC,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAEtF,uBAAU,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAE5C,uBAAU,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"ToolFunction.js","sourceRoot":"","sources":["../../src/function/ToolFunction.ts"],"names":[],"mappings":";;;AAAA,+CAAwE;AACxE,iDAA+D;AAC/D,gDAAkD;AAClD,sDAAmD;AAEnD;;;GAGG;AACH,MAAsB,YAAa,SAAQ,kBAAQ;IAEjD;;;;;OAKG;IACO,KAAK;QACb,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,OAAO;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAA,yBAAe,EAAC,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAEtF,uBAAU,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAE5C,uBAAU,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;QACvE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,aAAa;QACzB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE,CAAC;YACrC,OAAO,IAAI,kBAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YACnC,OAAO,IAAI,kBAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,4EAA4E;QAC5E,OAAO,sBAAY,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACzD,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,gBAAgB;QAC5B,OAAO,MAAM,IAAA,sCAA0B,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxD,CAAC;CACF;AAxDD,oCAwDC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolLogger.d.ts","sourceRoot":"","sources":["../../src/logging/ToolLogger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,mBAAmB,CAAC;AAEzC;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,
|
|
1
|
+
{"version":3,"file":"ToolLogger.d.ts","sourceRoot":"","sources":["../../src/logging/ToolLogger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,mBAAmB,CAAC;AAEzC;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAyCtC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAO;IAC/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAM;IAE7C;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IA0ClC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAO/B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAQrC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAarC;;OAEG;WACW,UAAU,CACtB,GAAG,EAAE,GAAG,CAAC,OAAO,GACf,IAAI;IAYP;;OAEG;WACW,WAAW,CACvB,GAAG,EAAE,GAAG,CAAC,OAAO,EAChB,QAAQ,EAAE,GAAG,CAAC,QAAQ,EACtB,gBAAgB,CAAC,EAAE,MAAM,GACxB,IAAI;CAeR"}
|
|
@@ -7,7 +7,9 @@ const app_sdk_1 = require("@zaiusinc/app-sdk");
|
|
|
7
7
|
*/
|
|
8
8
|
class ToolLogger {
|
|
9
9
|
static SENSITIVE_FIELDS = [
|
|
10
|
+
// Authentication / secrets
|
|
10
11
|
'password',
|
|
12
|
+
'pass',
|
|
11
13
|
'secret',
|
|
12
14
|
'key',
|
|
13
15
|
'token',
|
|
@@ -17,7 +19,31 @@ class ToolLogger {
|
|
|
17
19
|
'refresh_token',
|
|
18
20
|
'api_key',
|
|
19
21
|
'private_key',
|
|
20
|
-
'client_secret'
|
|
22
|
+
'client_secret',
|
|
23
|
+
'session_token',
|
|
24
|
+
'authorization',
|
|
25
|
+
// Payment-related
|
|
26
|
+
'card_number',
|
|
27
|
+
'credit_card',
|
|
28
|
+
'cvv',
|
|
29
|
+
'expiry_date',
|
|
30
|
+
// Personal info
|
|
31
|
+
'ssn', // social security number
|
|
32
|
+
'nid', // national ID
|
|
33
|
+
'passport',
|
|
34
|
+
'dob', // date of birth
|
|
35
|
+
'email',
|
|
36
|
+
'phone',
|
|
37
|
+
'address',
|
|
38
|
+
// Misc / environment
|
|
39
|
+
'otp',
|
|
40
|
+
'pin',
|
|
41
|
+
'security_answer',
|
|
42
|
+
'security_question',
|
|
43
|
+
'signing_key',
|
|
44
|
+
'encryption_key',
|
|
45
|
+
'jwt',
|
|
46
|
+
'bearer_token'
|
|
21
47
|
];
|
|
22
48
|
static MAX_PARAM_LENGTH = 100;
|
|
23
49
|
static MAX_ARRAY_ITEMS = 10;
|
|
@@ -102,7 +128,7 @@ class ToolLogger {
|
|
|
102
128
|
parameters: this.createParameterSummary(params)
|
|
103
129
|
};
|
|
104
130
|
// Log with Zaius audience so developers only see requests for accounts they have access to
|
|
105
|
-
app_sdk_1.logger.info(app_sdk_1.LogVisibility.Zaius, requestLog);
|
|
131
|
+
app_sdk_1.logger.info(app_sdk_1.LogVisibility.Zaius, JSON.stringify(requestLog));
|
|
106
132
|
}
|
|
107
133
|
/**
|
|
108
134
|
* Logs a successful response
|
|
@@ -118,7 +144,7 @@ class ToolLogger {
|
|
|
118
144
|
success: response.status >= 200 && response.status < 300
|
|
119
145
|
};
|
|
120
146
|
// Log with Zaius audience so developers only see requests for accounts they have access to
|
|
121
|
-
app_sdk_1.logger.info(app_sdk_1.LogVisibility.Zaius, responseLog);
|
|
147
|
+
app_sdk_1.logger.info(app_sdk_1.LogVisibility.Zaius, JSON.stringify(responseLog));
|
|
122
148
|
}
|
|
123
149
|
}
|
|
124
150
|
exports.ToolLogger = ToolLogger;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolLogger.js","sourceRoot":"","sources":["../../src/logging/ToolLogger.ts"],"names":[],"mappings":";;;AAAA,+CAA0D;AAG1D;;GAEG;AACH,MAAa,UAAU;IACb,MAAM,CAAU,gBAAgB,GAAG;QACzC,UAAU;QACV,QAAQ;QACR,KAAK;QACL,OAAO;QACP,MAAM;QACN,aAAa;QACb,cAAc;QACd,eAAe;QACf,SAAS;QACT,aAAa;QACb,eAAe;
|
|
1
|
+
{"version":3,"file":"ToolLogger.js","sourceRoot":"","sources":["../../src/logging/ToolLogger.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,10 @@ describe('ToolLogger', () => {
|
|
|
18
18
|
beforeEach(() => {
|
|
19
19
|
jest.clearAllMocks();
|
|
20
20
|
});
|
|
21
|
+
// Helper function to check JSON string logs
|
|
22
|
+
const expectJsonLog = (expectedData) => {
|
|
23
|
+
expect(mockLogger.info).toHaveBeenCalledWith(app_sdk_1.LogVisibility.Zaius, JSON.stringify(expectedData));
|
|
24
|
+
};
|
|
21
25
|
const createMockRequest = (overrides = {}) => {
|
|
22
26
|
const defaultRequest = {
|
|
23
27
|
path: '/test-tool',
|
|
@@ -51,25 +55,26 @@ describe('ToolLogger', () => {
|
|
|
51
55
|
it('should log request with parameters', () => {
|
|
52
56
|
const req = createMockRequest();
|
|
53
57
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
54
|
-
|
|
58
|
+
const expectedLog = {
|
|
55
59
|
event: 'opal_tool_request',
|
|
56
60
|
path: '/test-tool',
|
|
57
61
|
parameters: {
|
|
58
62
|
name: 'test',
|
|
59
63
|
value: 'data'
|
|
60
64
|
}
|
|
61
|
-
}
|
|
65
|
+
};
|
|
66
|
+
expect(mockLogger.info).toHaveBeenCalledWith(app_sdk_1.LogVisibility.Zaius, JSON.stringify(expectedLog));
|
|
62
67
|
});
|
|
63
68
|
it('should handle request without parameters', () => {
|
|
64
69
|
const req = createMockRequest({
|
|
65
70
|
bodyJSON: null
|
|
66
71
|
});
|
|
67
72
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
68
|
-
|
|
73
|
+
expectJsonLog({
|
|
69
74
|
event: 'opal_tool_request',
|
|
70
75
|
path: '/test-tool',
|
|
71
76
|
parameters: null
|
|
72
|
-
})
|
|
77
|
+
});
|
|
73
78
|
});
|
|
74
79
|
it('should use bodyJSON as parameters when no parameters field exists', () => {
|
|
75
80
|
const req = createMockRequest({
|
|
@@ -79,12 +84,14 @@ describe('ToolLogger', () => {
|
|
|
79
84
|
}
|
|
80
85
|
});
|
|
81
86
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
82
|
-
|
|
87
|
+
expectJsonLog({
|
|
88
|
+
event: 'opal_tool_request',
|
|
89
|
+
path: '/test-tool',
|
|
83
90
|
parameters: {
|
|
84
91
|
name: 'direct',
|
|
85
92
|
action: 'test'
|
|
86
93
|
}
|
|
87
|
-
})
|
|
94
|
+
});
|
|
88
95
|
});
|
|
89
96
|
it('should redact all sensitive field variations', () => {
|
|
90
97
|
const req = createMockRequest({
|
|
@@ -106,7 +113,9 @@ describe('ToolLogger', () => {
|
|
|
106
113
|
}
|
|
107
114
|
});
|
|
108
115
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
109
|
-
|
|
116
|
+
expectJsonLog({
|
|
117
|
+
event: 'opal_tool_request',
|
|
118
|
+
path: '/test-tool',
|
|
110
119
|
parameters: {
|
|
111
120
|
username: 'john',
|
|
112
121
|
password: '[REDACTED]',
|
|
@@ -121,7 +130,7 @@ describe('ToolLogger', () => {
|
|
|
121
130
|
client_secret: '[REDACTED]',
|
|
122
131
|
normal_field: 'visible'
|
|
123
132
|
}
|
|
124
|
-
})
|
|
133
|
+
});
|
|
125
134
|
});
|
|
126
135
|
it('should redact sensitive fields with case variations', () => {
|
|
127
136
|
const req = createMockRequest({
|
|
@@ -138,7 +147,9 @@ describe('ToolLogger', () => {
|
|
|
138
147
|
}
|
|
139
148
|
});
|
|
140
149
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
141
|
-
|
|
150
|
+
expectJsonLog({
|
|
151
|
+
event: 'opal_tool_request',
|
|
152
|
+
path: '/test-tool',
|
|
142
153
|
parameters: {
|
|
143
154
|
PASSWORD: '[REDACTED]',
|
|
144
155
|
API_KEY: '[REDACTED]',
|
|
@@ -148,7 +159,7 @@ describe('ToolLogger', () => {
|
|
|
148
159
|
ssh_key: '[REDACTED]',
|
|
149
160
|
normal_field: 'visible'
|
|
150
161
|
}
|
|
151
|
-
})
|
|
162
|
+
});
|
|
152
163
|
});
|
|
153
164
|
it('should truncate long string values', () => {
|
|
154
165
|
const longString = 'a'.repeat(150);
|
|
@@ -161,12 +172,14 @@ describe('ToolLogger', () => {
|
|
|
161
172
|
}
|
|
162
173
|
});
|
|
163
174
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
164
|
-
|
|
175
|
+
expectJsonLog({
|
|
176
|
+
event: 'opal_tool_request',
|
|
177
|
+
path: '/test-tool',
|
|
165
178
|
parameters: {
|
|
166
179
|
description: `${'a'.repeat(100)}... (truncated, 150 chars total)`,
|
|
167
180
|
short_field: 'normal'
|
|
168
181
|
}
|
|
169
|
-
})
|
|
182
|
+
});
|
|
170
183
|
});
|
|
171
184
|
it('should truncate large arrays', () => {
|
|
172
185
|
const largeArray = Array.from({ length: 15 }, (_, i) => `item${i}`);
|
|
@@ -179,7 +192,9 @@ describe('ToolLogger', () => {
|
|
|
179
192
|
}
|
|
180
193
|
});
|
|
181
194
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
182
|
-
|
|
195
|
+
expectJsonLog({
|
|
196
|
+
event: 'opal_tool_request',
|
|
197
|
+
path: '/test-tool',
|
|
183
198
|
parameters: {
|
|
184
199
|
items: [
|
|
185
200
|
...largeArray.slice(0, 10),
|
|
@@ -187,7 +202,7 @@ describe('ToolLogger', () => {
|
|
|
187
202
|
],
|
|
188
203
|
small_array: ['a', 'b']
|
|
189
204
|
}
|
|
190
|
-
})
|
|
205
|
+
});
|
|
191
206
|
});
|
|
192
207
|
it('should handle nested objects with sensitive fields', () => {
|
|
193
208
|
const req = createMockRequest({
|
|
@@ -210,11 +225,13 @@ describe('ToolLogger', () => {
|
|
|
210
225
|
}
|
|
211
226
|
});
|
|
212
227
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
213
|
-
|
|
228
|
+
expectJsonLog({
|
|
229
|
+
event: 'opal_tool_request',
|
|
230
|
+
path: '/test-tool',
|
|
214
231
|
parameters: {
|
|
215
232
|
user: {
|
|
216
233
|
name: 'John',
|
|
217
|
-
email: '
|
|
234
|
+
email: '[REDACTED]',
|
|
218
235
|
password: '[REDACTED]'
|
|
219
236
|
},
|
|
220
237
|
config: {
|
|
@@ -226,7 +243,7 @@ describe('ToolLogger', () => {
|
|
|
226
243
|
api_key: '[REDACTED]'
|
|
227
244
|
}
|
|
228
245
|
}
|
|
229
|
-
})
|
|
246
|
+
});
|
|
230
247
|
});
|
|
231
248
|
it('should handle null and undefined values', () => {
|
|
232
249
|
const req = createMockRequest({
|
|
@@ -242,16 +259,17 @@ describe('ToolLogger', () => {
|
|
|
242
259
|
}
|
|
243
260
|
});
|
|
244
261
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
245
|
-
|
|
262
|
+
expectJsonLog({
|
|
263
|
+
event: 'opal_tool_request',
|
|
264
|
+
path: '/test-tool',
|
|
246
265
|
parameters: {
|
|
247
266
|
nullValue: null,
|
|
248
|
-
undefinedValue: undefined,
|
|
249
267
|
emptyString: '',
|
|
250
268
|
zero: 0,
|
|
251
269
|
false: false,
|
|
252
270
|
password: '[REDACTED]'
|
|
253
271
|
}
|
|
254
|
-
})
|
|
272
|
+
});
|
|
255
273
|
});
|
|
256
274
|
it('should handle arrays in sensitive fields', () => {
|
|
257
275
|
const req = createMockRequest({
|
|
@@ -263,12 +281,14 @@ describe('ToolLogger', () => {
|
|
|
263
281
|
}
|
|
264
282
|
});
|
|
265
283
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
266
|
-
|
|
284
|
+
expectJsonLog({
|
|
285
|
+
event: 'opal_tool_request',
|
|
286
|
+
path: '/test-tool',
|
|
267
287
|
parameters: {
|
|
268
288
|
credentials: '[REDACTED]',
|
|
269
289
|
public_list: ['item1', 'item2']
|
|
270
290
|
}
|
|
271
|
-
})
|
|
291
|
+
});
|
|
272
292
|
});
|
|
273
293
|
it('should handle objects in sensitive fields', () => {
|
|
274
294
|
const req = createMockRequest({
|
|
@@ -286,7 +306,9 @@ describe('ToolLogger', () => {
|
|
|
286
306
|
}
|
|
287
307
|
});
|
|
288
308
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
289
|
-
|
|
309
|
+
expectJsonLog({
|
|
310
|
+
event: 'opal_tool_request',
|
|
311
|
+
path: '/test-tool',
|
|
290
312
|
parameters: {
|
|
291
313
|
auth: '[REDACTED]',
|
|
292
314
|
public_config: {
|
|
@@ -294,7 +316,7 @@ describe('ToolLogger', () => {
|
|
|
294
316
|
retries: 3
|
|
295
317
|
}
|
|
296
318
|
}
|
|
297
|
-
})
|
|
319
|
+
});
|
|
298
320
|
});
|
|
299
321
|
it('should respect max depth to prevent infinite recursion', () => {
|
|
300
322
|
const deepObject = { level: 0, data: 'test' };
|
|
@@ -317,7 +339,7 @@ describe('ToolLogger', () => {
|
|
|
317
339
|
const req = createMockRequest();
|
|
318
340
|
const response = createMockResponse(200, { result: 'success', data: 'test' });
|
|
319
341
|
ToolLogger_1.ToolLogger.logResponse(req, response, 150);
|
|
320
|
-
|
|
342
|
+
const expectedLog = {
|
|
321
343
|
event: 'opal_tool_response',
|
|
322
344
|
path: '/test-tool',
|
|
323
345
|
duration: '150ms',
|
|
@@ -325,46 +347,63 @@ describe('ToolLogger', () => {
|
|
|
325
347
|
contentType: 'application/json',
|
|
326
348
|
contentLength: 34, // JSON.stringify({ result: 'success', data: 'test' }).length
|
|
327
349
|
success: true
|
|
328
|
-
}
|
|
350
|
+
};
|
|
351
|
+
expect(mockLogger.info).toHaveBeenCalledWith(app_sdk_1.LogVisibility.Zaius, JSON.stringify(expectedLog));
|
|
329
352
|
});
|
|
330
353
|
it('should log error response', () => {
|
|
331
354
|
const req = createMockRequest();
|
|
332
355
|
const response = createMockResponse(400, { error: 'Bad request' });
|
|
333
356
|
ToolLogger_1.ToolLogger.logResponse(req, response, 75);
|
|
334
|
-
|
|
357
|
+
expectJsonLog({
|
|
335
358
|
event: 'opal_tool_response',
|
|
336
359
|
path: '/test-tool',
|
|
337
360
|
duration: '75ms',
|
|
338
361
|
status: 400,
|
|
362
|
+
contentType: 'application/json',
|
|
363
|
+
contentLength: 23,
|
|
339
364
|
success: false
|
|
340
|
-
})
|
|
365
|
+
});
|
|
341
366
|
});
|
|
342
367
|
it('should handle response without bodyJSON', () => {
|
|
343
368
|
const req = createMockRequest();
|
|
344
369
|
const response = createMockResponse(204);
|
|
345
370
|
response.bodyJSON = undefined;
|
|
346
371
|
ToolLogger_1.ToolLogger.logResponse(req, response);
|
|
347
|
-
|
|
372
|
+
expectJsonLog({
|
|
373
|
+
event: 'opal_tool_response',
|
|
374
|
+
path: '/test-tool',
|
|
375
|
+
status: 204,
|
|
376
|
+
contentType: 'application/json',
|
|
348
377
|
contentLength: 0,
|
|
349
378
|
success: true
|
|
350
|
-
})
|
|
379
|
+
});
|
|
351
380
|
});
|
|
352
381
|
it('should handle response without processing time', () => {
|
|
353
382
|
const req = createMockRequest();
|
|
354
383
|
const response = createMockResponse(200, { data: 'test' });
|
|
355
384
|
ToolLogger_1.ToolLogger.logResponse(req, response);
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
385
|
+
expectJsonLog({
|
|
386
|
+
event: 'opal_tool_response',
|
|
387
|
+
path: '/test-tool',
|
|
388
|
+
status: 200,
|
|
389
|
+
contentType: 'application/json',
|
|
390
|
+
contentLength: 15,
|
|
391
|
+
success: true
|
|
392
|
+
});
|
|
359
393
|
});
|
|
360
394
|
it('should handle unknown content type', () => {
|
|
361
395
|
const req = createMockRequest();
|
|
362
396
|
const response = createMockResponse(200, { data: 'test' });
|
|
363
397
|
response.headers.get = jest.fn().mockReturnValue(null);
|
|
364
398
|
ToolLogger_1.ToolLogger.logResponse(req, response);
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
399
|
+
expectJsonLog({
|
|
400
|
+
event: 'opal_tool_response',
|
|
401
|
+
path: '/test-tool',
|
|
402
|
+
status: 200,
|
|
403
|
+
contentType: 'unknown',
|
|
404
|
+
contentLength: 15,
|
|
405
|
+
success: true
|
|
406
|
+
});
|
|
368
407
|
});
|
|
369
408
|
it('should handle content length calculation error', () => {
|
|
370
409
|
const req = createMockRequest();
|
|
@@ -372,9 +411,14 @@ describe('ToolLogger', () => {
|
|
|
372
411
|
circularObj.self = circularObj; // Create circular reference
|
|
373
412
|
const response = createMockResponse(200, circularObj);
|
|
374
413
|
ToolLogger_1.ToolLogger.logResponse(req, response);
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
414
|
+
expectJsonLog({
|
|
415
|
+
event: 'opal_tool_response',
|
|
416
|
+
path: '/test-tool',
|
|
417
|
+
status: 200,
|
|
418
|
+
contentType: 'application/json',
|
|
419
|
+
contentLength: 'unknown',
|
|
420
|
+
success: true
|
|
421
|
+
});
|
|
378
422
|
});
|
|
379
423
|
it('should correctly identify success status codes', () => {
|
|
380
424
|
const req = createMockRequest();
|
|
@@ -392,9 +436,14 @@ describe('ToolLogger', () => {
|
|
|
392
436
|
mockLogger.info.mockClear();
|
|
393
437
|
const response = createMockResponse(status);
|
|
394
438
|
ToolLogger_1.ToolLogger.logResponse(req, response);
|
|
395
|
-
|
|
439
|
+
expectJsonLog({
|
|
440
|
+
event: 'opal_tool_response',
|
|
441
|
+
path: '/test-tool',
|
|
442
|
+
status,
|
|
443
|
+
contentType: 'application/json',
|
|
444
|
+
contentLength: 2,
|
|
396
445
|
success: expected
|
|
397
|
-
})
|
|
446
|
+
});
|
|
398
447
|
});
|
|
399
448
|
});
|
|
400
449
|
it('should handle different content types', () => {
|
|
@@ -410,9 +459,14 @@ describe('ToolLogger', () => {
|
|
|
410
459
|
const response = createMockResponse(200, { data: 'test' });
|
|
411
460
|
response.headers.get = jest.fn().mockReturnValue(contentType);
|
|
412
461
|
ToolLogger_1.ToolLogger.logResponse(req, response);
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
462
|
+
expectJsonLog({
|
|
463
|
+
event: 'opal_tool_response',
|
|
464
|
+
path: '/test-tool',
|
|
465
|
+
status: 200,
|
|
466
|
+
contentType,
|
|
467
|
+
contentLength: 15,
|
|
468
|
+
success: true
|
|
469
|
+
});
|
|
416
470
|
});
|
|
417
471
|
});
|
|
418
472
|
});
|
|
@@ -422,9 +476,11 @@ describe('ToolLogger', () => {
|
|
|
422
476
|
bodyJSON: {}
|
|
423
477
|
});
|
|
424
478
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
425
|
-
|
|
479
|
+
expectJsonLog({
|
|
480
|
+
event: 'opal_tool_request',
|
|
481
|
+
path: '/test-tool',
|
|
426
482
|
parameters: {}
|
|
427
|
-
})
|
|
483
|
+
});
|
|
428
484
|
});
|
|
429
485
|
it('should handle request with only parameters field', () => {
|
|
430
486
|
const req = createMockRequest({
|
|
@@ -435,11 +491,13 @@ describe('ToolLogger', () => {
|
|
|
435
491
|
}
|
|
436
492
|
});
|
|
437
493
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
438
|
-
|
|
494
|
+
expectJsonLog({
|
|
495
|
+
event: 'opal_tool_request',
|
|
496
|
+
path: '/test-tool',
|
|
439
497
|
parameters: {
|
|
440
498
|
field: 'value'
|
|
441
499
|
}
|
|
442
|
-
})
|
|
500
|
+
});
|
|
443
501
|
});
|
|
444
502
|
it('should handle mixed data types in parameters', () => {
|
|
445
503
|
const req = createMockRequest({
|
|
@@ -456,7 +514,9 @@ describe('ToolLogger', () => {
|
|
|
456
514
|
}
|
|
457
515
|
});
|
|
458
516
|
ToolLogger_1.ToolLogger.logRequest(req);
|
|
459
|
-
|
|
517
|
+
expectJsonLog({
|
|
518
|
+
event: 'opal_tool_request',
|
|
519
|
+
path: '/test-tool',
|
|
460
520
|
parameters: {
|
|
461
521
|
string: 'text',
|
|
462
522
|
number: 42,
|
|
@@ -466,7 +526,7 @@ describe('ToolLogger', () => {
|
|
|
466
526
|
nullValue: null,
|
|
467
527
|
password: '[REDACTED]'
|
|
468
528
|
}
|
|
469
|
-
})
|
|
529
|
+
});
|
|
470
530
|
});
|
|
471
531
|
});
|
|
472
532
|
});
|