@tellescope/sdk 1.253.1 → 1.254.1

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.
Files changed (124) hide show
  1. package/lib/cjs/sdk.d.ts +4 -0
  2. package/lib/cjs/sdk.d.ts.map +1 -1
  3. package/lib/cjs/tests/api_tests/_tmp_bc_verify.test.d.ts.map +1 -0
  4. package/lib/cjs/tests/api_tests/_tmp_blank_status_verify.test.d.ts.map +1 -0
  5. package/lib/cjs/tests/api_tests/_tmp_followup_verify.test.d.ts.map +1 -0
  6. package/lib/cjs/tests/api_tests/_tmp_nonmatch_verify.test.d.ts.map +1 -0
  7. package/lib/cjs/tests/api_tests/ai_decision_summary_config.test.d.ts +16 -0
  8. package/lib/cjs/tests/api_tests/ai_decision_summary_config.test.d.ts.map +1 -0
  9. package/lib/cjs/tests/api_tests/ai_decision_summary_config.test.js +187 -0
  10. package/lib/cjs/tests/api_tests/ai_decision_summary_config.test.js.map +1 -0
  11. package/lib/cjs/tests/api_tests/field_redaction.test.d.ts.map +1 -1
  12. package/lib/cjs/tests/api_tests/field_redaction.test.js +112 -99
  13. package/lib/cjs/tests/api_tests/field_redaction.test.js.map +1 -1
  14. package/lib/cjs/tests/api_tests/journey_error_branching.test.js +7 -2
  15. package/lib/cjs/tests/api_tests/journey_error_branching.test.js.map +1 -1
  16. package/lib/cjs/tests/api_tests/mdi_case_offerings.test.d.ts +6 -0
  17. package/lib/cjs/tests/api_tests/mdi_case_offerings.test.d.ts.map +1 -0
  18. package/lib/cjs/tests/api_tests/mdi_case_offerings.test.js +443 -0
  19. package/lib/cjs/tests/api_tests/mdi_case_offerings.test.js.map +1 -0
  20. package/lib/cjs/tests/api_tests/resource_access_tags.test.d.ts +22 -0
  21. package/lib/cjs/tests/api_tests/resource_access_tags.test.d.ts.map +1 -0
  22. package/lib/cjs/tests/api_tests/resource_access_tags.test.js +488 -0
  23. package/lib/cjs/tests/api_tests/resource_access_tags.test.js.map +1 -0
  24. package/lib/cjs/tests/api_tests/security/F-0116-F-0119-enduser-cross-create.test.d.ts +21 -0
  25. package/lib/cjs/tests/api_tests/security/F-0116-F-0119-enduser-cross-create.test.d.ts.map +1 -0
  26. package/lib/cjs/tests/api_tests/security/F-0116-F-0119-enduser-cross-create.test.js +362 -0
  27. package/lib/cjs/tests/api_tests/security/F-0116-F-0119-enduser-cross-create.test.js.map +1 -0
  28. package/lib/cjs/tests/api_tests/security/F-0145-globalunique-leak.test.d.ts +20 -0
  29. package/lib/cjs/tests/api_tests/security/F-0145-globalunique-leak.test.d.ts.map +1 -0
  30. package/lib/cjs/tests/api_tests/security/F-0145-globalunique-leak.test.js +139 -0
  31. package/lib/cjs/tests/api_tests/security/F-0145-globalunique-leak.test.js.map +1 -0
  32. package/lib/cjs/tests/api_tests/security/F-0151-load-inbox-redaction.test.d.ts +18 -0
  33. package/lib/cjs/tests/api_tests/security/F-0151-load-inbox-redaction.test.d.ts.map +1 -0
  34. package/lib/cjs/tests/api_tests/security/F-0151-load-inbox-redaction.test.js +156 -0
  35. package/lib/cjs/tests/api_tests/security/F-0151-load-inbox-redaction.test.js.map +1 -0
  36. package/lib/cjs/tests/api_tests/security/F-0155-webhook-timeout.test.d.ts +20 -0
  37. package/lib/cjs/tests/api_tests/security/F-0155-webhook-timeout.test.d.ts.map +1 -0
  38. package/lib/cjs/tests/api_tests/security/F-0155-webhook-timeout.test.js +157 -0
  39. package/lib/cjs/tests/api_tests/security/F-0155-webhook-timeout.test.js.map +1 -0
  40. package/lib/cjs/tests/api_tests/time_tracks.test.d.ts +8 -0
  41. package/lib/cjs/tests/api_tests/time_tracks.test.d.ts.map +1 -1
  42. package/lib/cjs/tests/api_tests/time_tracks.test.js +638 -1
  43. package/lib/cjs/tests/api_tests/time_tracks.test.js.map +1 -1
  44. package/lib/cjs/tests/setup.d.ts.map +1 -1
  45. package/lib/cjs/tests/setup.js +20 -1
  46. package/lib/cjs/tests/setup.js.map +1 -1
  47. package/lib/cjs/tests/tests.d.ts.map +1 -1
  48. package/lib/cjs/tests/tests.js +606 -178
  49. package/lib/cjs/tests/tests.js.map +1 -1
  50. package/lib/esm/sdk.d.ts +6 -2
  51. package/lib/esm/sdk.d.ts.map +1 -1
  52. package/lib/esm/tests/api_tests/_tmp_bc_verify.test.d.ts +2 -0
  53. package/lib/esm/tests/api_tests/_tmp_bc_verify.test.d.ts.map +1 -0
  54. package/lib/esm/tests/api_tests/_tmp_bc_verify.test.js +120 -0
  55. package/lib/esm/tests/api_tests/_tmp_bc_verify.test.js.map +1 -0
  56. package/lib/esm/tests/api_tests/_tmp_blank_status_verify.test.d.ts +2 -0
  57. package/lib/esm/tests/api_tests/_tmp_blank_status_verify.test.d.ts.map +1 -0
  58. package/lib/esm/tests/api_tests/_tmp_blank_status_verify.test.js +200 -0
  59. package/lib/esm/tests/api_tests/_tmp_blank_status_verify.test.js.map +1 -0
  60. package/lib/esm/tests/api_tests/_tmp_followup_verify.test.d.ts +2 -0
  61. package/lib/esm/tests/api_tests/_tmp_followup_verify.test.d.ts.map +1 -0
  62. package/lib/esm/tests/api_tests/_tmp_followup_verify.test.js +194 -0
  63. package/lib/esm/tests/api_tests/_tmp_followup_verify.test.js.map +1 -0
  64. package/lib/esm/tests/api_tests/_tmp_nonmatch_verify.test.d.ts +2 -0
  65. package/lib/esm/tests/api_tests/_tmp_nonmatch_verify.test.d.ts.map +1 -0
  66. package/lib/esm/tests/api_tests/_tmp_nonmatch_verify.test.js +115 -0
  67. package/lib/esm/tests/api_tests/_tmp_nonmatch_verify.test.js.map +1 -0
  68. package/lib/esm/tests/api_tests/ai_decision_summary_config.test.d.ts +16 -0
  69. package/lib/esm/tests/api_tests/ai_decision_summary_config.test.d.ts.map +1 -0
  70. package/lib/esm/tests/api_tests/ai_decision_summary_config.test.js +183 -0
  71. package/lib/esm/tests/api_tests/ai_decision_summary_config.test.js.map +1 -0
  72. package/lib/esm/tests/api_tests/field_redaction.test.d.ts.map +1 -1
  73. package/lib/esm/tests/api_tests/field_redaction.test.js +112 -99
  74. package/lib/esm/tests/api_tests/field_redaction.test.js.map +1 -1
  75. package/lib/esm/tests/api_tests/journey_error_branching.test.js +7 -2
  76. package/lib/esm/tests/api_tests/journey_error_branching.test.js.map +1 -1
  77. package/lib/esm/tests/api_tests/mdi_case_offerings.test.d.ts +6 -0
  78. package/lib/esm/tests/api_tests/mdi_case_offerings.test.d.ts.map +1 -0
  79. package/lib/esm/tests/api_tests/mdi_case_offerings.test.js +439 -0
  80. package/lib/esm/tests/api_tests/mdi_case_offerings.test.js.map +1 -0
  81. package/lib/esm/tests/api_tests/resource_access_tags.test.d.ts +22 -0
  82. package/lib/esm/tests/api_tests/resource_access_tags.test.d.ts.map +1 -0
  83. package/lib/esm/tests/api_tests/resource_access_tags.test.js +484 -0
  84. package/lib/esm/tests/api_tests/resource_access_tags.test.js.map +1 -0
  85. package/lib/esm/tests/api_tests/security/F-0116-F-0119-enduser-cross-create.test.d.ts +21 -0
  86. package/lib/esm/tests/api_tests/security/F-0116-F-0119-enduser-cross-create.test.d.ts.map +1 -0
  87. package/lib/esm/tests/api_tests/security/F-0116-F-0119-enduser-cross-create.test.js +358 -0
  88. package/lib/esm/tests/api_tests/security/F-0116-F-0119-enduser-cross-create.test.js.map +1 -0
  89. package/lib/esm/tests/api_tests/security/F-0145-globalunique-leak.test.d.ts +20 -0
  90. package/lib/esm/tests/api_tests/security/F-0145-globalunique-leak.test.d.ts.map +1 -0
  91. package/lib/esm/tests/api_tests/security/F-0145-globalunique-leak.test.js +135 -0
  92. package/lib/esm/tests/api_tests/security/F-0145-globalunique-leak.test.js.map +1 -0
  93. package/lib/esm/tests/api_tests/security/F-0151-load-inbox-redaction.test.d.ts +18 -0
  94. package/lib/esm/tests/api_tests/security/F-0151-load-inbox-redaction.test.d.ts.map +1 -0
  95. package/lib/esm/tests/api_tests/security/F-0151-load-inbox-redaction.test.js +152 -0
  96. package/lib/esm/tests/api_tests/security/F-0151-load-inbox-redaction.test.js.map +1 -0
  97. package/lib/esm/tests/api_tests/security/F-0155-webhook-timeout.test.d.ts +20 -0
  98. package/lib/esm/tests/api_tests/security/F-0155-webhook-timeout.test.d.ts.map +1 -0
  99. package/lib/esm/tests/api_tests/security/F-0155-webhook-timeout.test.js +150 -0
  100. package/lib/esm/tests/api_tests/security/F-0155-webhook-timeout.test.js.map +1 -0
  101. package/lib/esm/tests/api_tests/time_tracks.test.d.ts +8 -0
  102. package/lib/esm/tests/api_tests/time_tracks.test.d.ts.map +1 -1
  103. package/lib/esm/tests/api_tests/time_tracks.test.js +635 -0
  104. package/lib/esm/tests/api_tests/time_tracks.test.js.map +1 -1
  105. package/lib/esm/tests/setup.d.ts.map +1 -1
  106. package/lib/esm/tests/setup.js +20 -1
  107. package/lib/esm/tests/setup.js.map +1 -1
  108. package/lib/esm/tests/tests.d.ts.map +1 -1
  109. package/lib/esm/tests/tests.js +607 -179
  110. package/lib/esm/tests/tests.js.map +1 -1
  111. package/lib/tsconfig.tsbuildinfo +1 -1
  112. package/package.json +10 -10
  113. package/src/tests/api_tests/field_redaction.test.ts +13 -0
  114. package/src/tests/api_tests/journey_error_branching.test.ts +5 -1
  115. package/src/tests/api_tests/mdi_case_offerings.test.ts +414 -0
  116. package/src/tests/api_tests/resource_access_tags.test.ts +303 -0
  117. package/src/tests/api_tests/security/F-0116-F-0119-enduser-cross-create.test.ts +221 -0
  118. package/src/tests/api_tests/security/F-0145-globalunique-leak.test.ts +78 -0
  119. package/src/tests/api_tests/security/F-0151-load-inbox-redaction.test.ts +81 -0
  120. package/src/tests/api_tests/security/F-0155-webhook-timeout.test.ts +85 -0
  121. package/src/tests/api_tests/time_tracks.test.ts +420 -0
  122. package/src/tests/setup.ts +9 -0
  123. package/src/tests/tests.ts +308 -5
  124. package/test_generated.pdf +0 -0
@@ -0,0 +1,156 @@
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
+ exports.load_inbox_redaction_tests = void 0;
40
+ require('source-map-support').install();
41
+ var sdk_1 = require("../../../sdk");
42
+ var testing_1 = require("@tellescope/testing");
43
+ var setup_1 = require("../../setup");
44
+ var host = process.env.API_URL || 'http://localhost:8080';
45
+ var ENDUSER_PASSWORD = 'F0151TestPassword!123';
46
+ /**
47
+ * Regression test for F-0151
48
+ * (security-audit/findings/F-0151-load-inbox-data-endusers-unredacted.md).
49
+ *
50
+ * load_inbox_data serialized $lookup'ed endusers via convert_id_name only (NOT applyRedactions),
51
+ * so endusers.hashedPassword (redactions:['all']) leaked to staff sessions — while the sibling
52
+ * phone_calls in the same response correctly went through applyRedactions.
53
+ *
54
+ * Repro: create an enduser, set their portal password (→ hashedPassword), seed an inbound
55
+ * (logOnly) email so the enduser appears in the inbox join, then load_inbox_data as staff and
56
+ * assert the returned enduser entry has NO hashedPassword.
57
+ */
58
+ var load_inbox_redaction_tests = function (_a) {
59
+ var sdk = _a.sdk;
60
+ return __awaiter(void 0, void 0, void 0, function () {
61
+ var enduserId, emailId, email, enduser_1, seeded, _b, _c;
62
+ return __generator(this, function (_d) {
63
+ switch (_d.label) {
64
+ case 0:
65
+ (0, testing_1.log_header)("F-0151: load_inbox_data enduser redaction");
66
+ _d.label = 1;
67
+ case 1:
68
+ _d.trys.push([1, , 6, 15]);
69
+ email = "f0151-enduser-".concat(Date.now(), "@example.com");
70
+ return [4 /*yield*/, sdk.api.endusers.createOne({ email: email, fname: 'F0151', lname: 'Inbox' })];
71
+ case 2:
72
+ enduser_1 = _d.sent();
73
+ enduserId = enduser_1.id;
74
+ return [4 /*yield*/, sdk.api.endusers.set_password({ id: enduser_1.id, password: ENDUSER_PASSWORD })
75
+ // Seed an inbound logOnly email so the enduser is joined into the inbox payload
76
+ ];
77
+ case 3:
78
+ _d.sent();
79
+ return [4 /*yield*/, sdk.api.emails.createOne({
80
+ enduserId: enduser_1.id, subject: 'F0151 seed', textContent: 'seed',
81
+ logOnly: true, inbound: true,
82
+ })];
83
+ case 4:
84
+ seeded = _d.sent();
85
+ emailId = seeded.id;
86
+ return [4 /*yield*/, (0, testing_1.async_test)('F-0151: load_inbox_data does not leak enduser.hashedPassword to staff', function () { return sdk.api.endusers.load_inbox_data({ enduserIds: [enduser_1.id] }); }, {
87
+ onResult: function (r) {
88
+ var _a;
89
+ var returned = ((_a = r === null || r === void 0 ? void 0 : r.endusers) !== null && _a !== void 0 ? _a : []).find(function (e) { var _a; return ((_a = (e.id || e._id)) === null || _a === void 0 ? void 0 : _a.toString()) === enduserId; });
90
+ // require that the enduser actually came back (so the assertion is meaningful),
91
+ // and that hashedPassword is absent
92
+ return !!returned && !('hashedPassword' in returned);
93
+ },
94
+ })];
95
+ case 5:
96
+ _d.sent();
97
+ return [3 /*break*/, 15];
98
+ case 6:
99
+ if (!emailId) return [3 /*break*/, 10];
100
+ _d.label = 7;
101
+ case 7:
102
+ _d.trys.push([7, 9, , 10]);
103
+ return [4 /*yield*/, sdk.api.emails.deleteOne(emailId)];
104
+ case 8:
105
+ _d.sent();
106
+ return [3 /*break*/, 10];
107
+ case 9:
108
+ _b = _d.sent();
109
+ return [3 /*break*/, 10];
110
+ case 10:
111
+ if (!enduserId) return [3 /*break*/, 14];
112
+ _d.label = 11;
113
+ case 11:
114
+ _d.trys.push([11, 13, , 14]);
115
+ return [4 /*yield*/, sdk.api.endusers.deleteOne(enduserId)];
116
+ case 12:
117
+ _d.sent();
118
+ return [3 /*break*/, 14];
119
+ case 13:
120
+ _c = _d.sent();
121
+ return [3 /*break*/, 14];
122
+ case 14: return [7 /*endfinally*/];
123
+ case 15: return [2 /*return*/];
124
+ }
125
+ });
126
+ });
127
+ };
128
+ exports.load_inbox_redaction_tests = load_inbox_redaction_tests;
129
+ if (require.main === module) {
130
+ console.log("\uD83C\uDF10 Using API URL: ".concat(host));
131
+ var sdk_2 = new sdk_1.Session({ host: host });
132
+ var sdkNonAdmin_1 = new sdk_1.Session({ host: host });
133
+ var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
134
+ return __generator(this, function (_a) {
135
+ switch (_a.label) {
136
+ case 0: return [4 /*yield*/, (0, setup_1.setup_tests)(sdk_2, sdkNonAdmin_1)];
137
+ case 1:
138
+ _a.sent();
139
+ return [4 /*yield*/, (0, exports.load_inbox_redaction_tests)({ sdk: sdk_2, sdkNonAdmin: sdkNonAdmin_1 })];
140
+ case 2:
141
+ _a.sent();
142
+ return [2 /*return*/];
143
+ }
144
+ });
145
+ }); };
146
+ runTests()
147
+ .then(function () {
148
+ console.log("✅ F-0151 load_inbox_data redaction test suite completed successfully");
149
+ process.exit(0);
150
+ })
151
+ .catch(function (error) {
152
+ console.error("❌ F-0151 load_inbox_data redaction test suite failed:", error);
153
+ process.exit(1);
154
+ });
155
+ }
156
+ //# sourceMappingURL=F-0151-load-inbox-redaction.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"F-0151-load-inbox-redaction.test.js","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/F-0151-load-inbox-redaction.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { Session } from "../../../sdk";
2
+ /**
3
+ * Regression test for F-0155
4
+ * (security-audit/findings/F-0155-outbound-webhook-no-timeout-slow-loris.md).
5
+ *
6
+ * Outbound webhook delivery used axios.post(url, ...) with no `timeout` (axios default = infinite).
7
+ * A tenant-controlled receiver that accepts the connection and never responds hangs the awaited
8
+ * request indefinitely (slow-loris → worker exhaustion). Fix: timeout: 15_000 on the axios calls.
9
+ *
10
+ * Repro: stand up a local HTTP server that accepts the connection but NEVER responds, point
11
+ * send_automation_webhook (which awaits the axios call) at it, and race the call against a 20s
12
+ * client timer.
13
+ * - green (fixed): server times out at ~15s → handler returns 400 → SDK call rejects < 20s
14
+ * - red (unfixed): the call is still pending at 20s → client timer wins
15
+ */
16
+ export declare const webhook_timeout_tests: ({ sdk }: {
17
+ sdk: Session;
18
+ sdkNonAdmin: Session;
19
+ }) => Promise<void>;
20
+ //# sourceMappingURL=F-0155-webhook-timeout.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"F-0155-webhook-timeout.test.d.ts","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/F-0155-webhook-timeout.test.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAYtC;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB;SAA2B,OAAO;iBAAe,OAAO;mBAkCzF,CAAA"}
@@ -0,0 +1,157 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.webhook_timeout_tests = void 0;
43
+ require('source-map-support').install();
44
+ var http_1 = __importDefault(require("http"));
45
+ var sdk_1 = require("../../../sdk");
46
+ var testing_1 = require("@tellescope/testing");
47
+ var setup_1 = require("../../setup");
48
+ var host = process.env.API_URL || 'http://localhost:8080';
49
+ // The server-side axios timeout is 15s (F-0155 fix). We bound our own wait above that.
50
+ var CLIENT_WAIT_MS = 20000;
51
+ /**
52
+ * Regression test for F-0155
53
+ * (security-audit/findings/F-0155-outbound-webhook-no-timeout-slow-loris.md).
54
+ *
55
+ * Outbound webhook delivery used axios.post(url, ...) with no `timeout` (axios default = infinite).
56
+ * A tenant-controlled receiver that accepts the connection and never responds hangs the awaited
57
+ * request indefinitely (slow-loris → worker exhaustion). Fix: timeout: 15_000 on the axios calls.
58
+ *
59
+ * Repro: stand up a local HTTP server that accepts the connection but NEVER responds, point
60
+ * send_automation_webhook (which awaits the axios call) at it, and race the call against a 20s
61
+ * client timer.
62
+ * - green (fixed): server times out at ~15s → handler returns 400 → SDK call rejects < 20s
63
+ * - red (unfixed): the call is still pending at 20s → client timer wins
64
+ */
65
+ var webhook_timeout_tests = function (_a) {
66
+ var sdk = _a.sdk;
67
+ return __awaiter(void 0, void 0, void 0, function () {
68
+ var enduserId, slowServer, port, blackholeUrl_1, enduser_1, _b;
69
+ return __generator(this, function (_c) {
70
+ switch (_c.label) {
71
+ case 0:
72
+ (0, testing_1.log_header)("F-0155: outbound webhook timeout");
73
+ slowServer = http_1.default.createServer(function () { });
74
+ _c.label = 1;
75
+ case 1:
76
+ _c.trys.push([1, , 5, 10]);
77
+ return [4 /*yield*/, new Promise(function (resolve) { return slowServer.listen(0, '127.0.0.1', function () { return resolve(); }); })];
78
+ case 2:
79
+ _c.sent();
80
+ port = slowServer.address().port;
81
+ blackholeUrl_1 = "http://127.0.0.1:".concat(port, "/hook");
82
+ return [4 /*yield*/, sdk.api.endusers.createOne({ email: "f0155-".concat(Date.now(), "@example.com"), fname: 'F0155', lname: 'Webhook' })];
83
+ case 3:
84
+ enduser_1 = _c.sent();
85
+ enduserId = enduser_1.id;
86
+ return [4 /*yield*/, (0, testing_1.async_test)('F-0155: outbound webhook to a non-responding receiver times out server-side (does not hang)', function () { return __awaiter(void 0, void 0, void 0, function () {
87
+ var start, outcome;
88
+ return __generator(this, function (_a) {
89
+ switch (_a.label) {
90
+ case 0:
91
+ start = Date.now();
92
+ return [4 /*yield*/, Promise.race([
93
+ sdk.api.webhooks.send_automation_webhook({
94
+ enduserId: enduser_1.id,
95
+ action: { info: { url: blackholeUrl_1 } },
96
+ }).then(function () { return 'completed'; }).catch(function () { return 'errored'; }),
97
+ new Promise(function (r) { return setTimeout(function () { return r('client-timeout'); }, CLIENT_WAIT_MS); }),
98
+ ])];
99
+ case 1:
100
+ outcome = _a.sent();
101
+ return [2 /*return*/, { outcome: outcome, elapsed: Date.now() - start }];
102
+ }
103
+ });
104
+ }); },
105
+ // green: the server-side axios timeout fired (call settled) before our 20s client wait
106
+ { onResult: function (r) { return r.outcome !== 'client-timeout' && r.elapsed < CLIENT_WAIT_MS; } })];
107
+ case 4:
108
+ _c.sent();
109
+ return [3 /*break*/, 10];
110
+ case 5:
111
+ slowServer.close();
112
+ if (!enduserId) return [3 /*break*/, 9];
113
+ _c.label = 6;
114
+ case 6:
115
+ _c.trys.push([6, 8, , 9]);
116
+ return [4 /*yield*/, sdk.api.endusers.deleteOne(enduserId)];
117
+ case 7:
118
+ _c.sent();
119
+ return [3 /*break*/, 9];
120
+ case 8:
121
+ _b = _c.sent();
122
+ return [3 /*break*/, 9];
123
+ case 9: return [7 /*endfinally*/];
124
+ case 10: return [2 /*return*/];
125
+ }
126
+ });
127
+ });
128
+ };
129
+ exports.webhook_timeout_tests = webhook_timeout_tests;
130
+ if (require.main === module) {
131
+ console.log("\uD83C\uDF10 Using API URL: ".concat(host));
132
+ var sdk_2 = new sdk_1.Session({ host: host });
133
+ var sdkNonAdmin_1 = new sdk_1.Session({ host: host });
134
+ var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
135
+ return __generator(this, function (_a) {
136
+ switch (_a.label) {
137
+ case 0: return [4 /*yield*/, (0, setup_1.setup_tests)(sdk_2, sdkNonAdmin_1)];
138
+ case 1:
139
+ _a.sent();
140
+ return [4 /*yield*/, (0, exports.webhook_timeout_tests)({ sdk: sdk_2, sdkNonAdmin: sdkNonAdmin_1 })];
141
+ case 2:
142
+ _a.sent();
143
+ return [2 /*return*/];
144
+ }
145
+ });
146
+ }); };
147
+ runTests()
148
+ .then(function () {
149
+ console.log("✅ F-0155 webhook timeout test suite completed successfully");
150
+ process.exit(0);
151
+ })
152
+ .catch(function (error) {
153
+ console.error("❌ F-0155 webhook timeout test suite failed:", error);
154
+ process.exit(1);
155
+ });
156
+ }
157
+ //# sourceMappingURL=F-0155-webhook-timeout.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"F-0155-webhook-timeout.test.js","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/F-0155-webhook-timeout.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,CAAC,oBAAoB,CAAC,CAAC,OAAO,EAAE,CAAC;AAExC,8CAAuB;AACvB,oCAAsC;AACtC,+CAG4B;AAC5B,qCAAyC;AAEzC,IAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,uBAAgC,CAAA;AAEpE,uFAAuF;AACvF,IAAM,cAAc,GAAG,KAAM,CAAA;AAE7B;;;;;;;;;;;;;GAaG;AACI,IAAM,qBAAqB,GAAG,UAAO,EAAgD;QAA9C,GAAG,SAAA;;;;;;oBAC/C,IAAA,oBAAU,EAAC,kCAAkC,CAAC,CAAA;oBAGxC,UAAU,GAAG,cAAI,CAAC,YAAY,CAAC,cAA+C,CAAC,CAAC,CAAA;;;;oBAGpF,qBAAM,IAAI,OAAO,CAAO,UAAA,OAAO,IAAI,OAAA,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,cAAM,OAAA,OAAO,EAAE,EAAT,CAAS,CAAC,EAAlD,CAAkD,CAAC,EAAA;;oBAAtF,SAAsF,CAAA;oBAChF,IAAI,GAAI,UAAU,CAAC,OAAO,EAAU,CAAC,IAAI,CAAA;oBACzC,iBAAe,2BAAoB,IAAI,UAAO,CAAA;oBAEpC,qBAAM,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,gBAAS,IAAI,CAAC,GAAG,EAAE,iBAAc,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAA;;oBAA1H,YAAU,SAAgH;oBAChI,SAAS,GAAG,SAAO,CAAC,EAAE,CAAA;oBAEtB,qBAAM,IAAA,oBAAU,EACd,6FAA6F,EAC7F;;;;;wCACQ,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;wCACR,qBAAM,OAAO,CAAC,IAAI,CAAC;gDACjC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,uBAAuB,CAAC;oDACvC,SAAS,EAAE,SAAO,CAAC,EAAE;oDACrB,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,cAAY,EAAE,EAAE;iDACjC,CAAC,CAAC,IAAI,CAAC,cAAM,OAAA,WAAW,EAAX,CAAW,CAAC,CAAC,KAAK,CAAC,cAAM,OAAA,SAAS,EAAT,CAAS,CAAC;gDACxD,IAAI,OAAO,CAAS,UAAA,CAAC,IAAI,OAAA,UAAU,CAAC,cAAM,OAAA,CAAC,CAAC,gBAAgB,CAAC,EAAnB,CAAmB,EAAE,cAAc,CAAC,EAArD,CAAqD,CAAC;6CAChF,CAAC,EAAA;;wCANI,OAAO,GAAG,SAMd;wCACF,sBAAO,EAAE,OAAO,SAAA,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,EAAA;;;6BAChD;wBACD,uFAAuF;wBACvF,EAAE,QAAQ,EAAE,UAAC,CAAM,IAAK,OAAA,CAAC,CAAC,OAAO,KAAK,gBAAgB,IAAI,CAAC,CAAC,OAAO,GAAG,cAAc,EAA5D,CAA4D,EAAE,CACvF,EAAA;;oBAfD,SAeC,CAAA;;;oBAED,UAAU,CAAC,KAAK,EAAE,CAAA;yBACd,SAAS,EAAT,wBAAS;;;;oBAAU,qBAAM,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,EAAA;;oBAA3C,SAA2C,CAAA;;;;;;;;;;CAErE,CAAA;AAlCY,QAAA,qBAAqB,yBAkCjC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE;IAC3B,OAAO,CAAC,GAAG,CAAC,sCAAqB,IAAI,CAAE,CAAC,CAAA;IACxC,IAAM,KAAG,GAAG,IAAI,aAAO,CAAC,EAAE,IAAI,MAAA,EAAE,CAAC,CAAA;IACjC,IAAM,aAAW,GAAG,IAAI,aAAO,CAAC,EAAE,IAAI,MAAA,EAAE,CAAC,CAAA;IAEzC,IAAM,QAAQ,GAAG;;;wBACf,qBAAM,IAAA,mBAAW,EAAC,KAAG,EAAE,aAAW,CAAC,EAAA;;oBAAnC,SAAmC,CAAA;oBACnC,qBAAM,IAAA,6BAAqB,EAAC,EAAE,GAAG,OAAA,EAAE,WAAW,eAAA,EAAE,CAAC,EAAA;;oBAAjD,SAAiD,CAAA;;;;SAClD,CAAA;IAED,QAAQ,EAAE;SACP,IAAI,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAA;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC;SACD,KAAK,CAAC,UAAC,KAAK;QACX,OAAO,CAAC,KAAK,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAA;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;CACL"}
@@ -23,4 +23,12 @@ export declare const time_tracks_edge_case_tests: ({ sdk, sdkNonAdmin }: {
23
23
  sdk: Session;
24
24
  sdkNonAdmin: Session;
25
25
  }) => Promise<void>;
26
+ export declare const time_tracks_resubmit_tests: ({ sdk, sdkNonAdmin }: {
27
+ sdk: Session;
28
+ sdkNonAdmin: Session;
29
+ }) => Promise<void>;
30
+ export declare const time_tracks_appointment_duration_tests: ({ sdk, sdkNonAdmin }: {
31
+ sdk: Session;
32
+ sdkNonAdmin: Session;
33
+ }) => Promise<void>;
26
34
  //# sourceMappingURL=time_tracks.test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"time_tracks.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/api_tests/time_tracks.test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkFnC,eAAO,MAAM,iBAAiB;SAAuC,OAAO;iBAAe,OAAO;mBA0JjG,CAAA;AAKD,eAAO,MAAM,4BAA4B;SAAuC,OAAO;iBAAe,OAAO;mBAoF5G,CAAA;AAKD,eAAO,MAAM,4BAA4B;SAAuC,OAAO;iBAAe,OAAO;mBAsH5G,CAAA;AAKD,eAAO,MAAM,wBAAwB;SAAuC,OAAO;iBAAe,OAAO;mBA+GxG,CAAA;AAKD,eAAO,MAAM,sBAAsB;SAAuC,OAAO;iBAAe,OAAO;mBAqGtG,CAAA;AAKD,eAAO,MAAM,2BAA2B;SAAuC,OAAO;iBAAe,OAAO;mBAsE3G,CAAA"}
1
+ {"version":3,"file":"time_tracks.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/api_tests/time_tracks.test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkFnC,eAAO,MAAM,iBAAiB;SAAuC,OAAO;iBAAe,OAAO;mBA0JjG,CAAA;AAKD,eAAO,MAAM,4BAA4B;SAAuC,OAAO;iBAAe,OAAO;mBAoF5G,CAAA;AAKD,eAAO,MAAM,4BAA4B;SAAuC,OAAO;iBAAe,OAAO;mBAsH5G,CAAA;AAKD,eAAO,MAAM,wBAAwB;SAAuC,OAAO;iBAAe,OAAO;mBA+GxG,CAAA;AAKD,eAAO,MAAM,sBAAsB;SAAuC,OAAO;iBAAe,OAAO;mBAqGtG,CAAA;AAKD,eAAO,MAAM,2BAA2B;SAAuC,OAAO;iBAAe,OAAO;mBAsE3G,CAAA;AAKD,eAAO,MAAM,0BAA0B;SAAuC,OAAO;iBAAe,OAAO;mBA6M1G,CAAA;AAKD,eAAO,MAAM,sCAAsC;SAAuC,OAAO;iBAAe,OAAO;mBA2MtH,CAAA"}