@tellescope/sdk 1.250.2 → 1.252.0

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 (136) hide show
  1. package/lib/cjs/sdk.d.ts +9 -0
  2. package/lib/cjs/sdk.d.ts.map +1 -1
  3. package/lib/cjs/sdk.js +3 -0
  4. package/lib/cjs/sdk.js.map +1 -1
  5. package/lib/cjs/tests/api_tests/account_switcher.test.d.ts.map +1 -1
  6. package/lib/cjs/tests/api_tests/account_switcher.test.js +1700 -306
  7. package/lib/cjs/tests/api_tests/account_switcher.test.js.map +1 -1
  8. package/lib/cjs/tests/api_tests/calendar_event_webhook_template.test.d.ts +6 -0
  9. package/lib/cjs/tests/api_tests/calendar_event_webhook_template.test.d.ts.map +1 -0
  10. package/lib/cjs/tests/api_tests/calendar_event_webhook_template.test.js +337 -0
  11. package/lib/cjs/tests/api_tests/calendar_event_webhook_template.test.js.map +1 -0
  12. package/lib/cjs/tests/api_tests/enduser_login.test.d.ts +6 -0
  13. package/lib/cjs/tests/api_tests/enduser_login.test.d.ts.map +1 -0
  14. package/lib/cjs/tests/api_tests/enduser_login.test.js +315 -0
  15. package/lib/cjs/tests/api_tests/enduser_login.test.js.map +1 -0
  16. package/lib/cjs/tests/api_tests/enduser_login_rate_limits.test.d.ts +6 -0
  17. package/lib/cjs/tests/api_tests/enduser_login_rate_limits.test.d.ts.map +1 -0
  18. package/lib/cjs/tests/api_tests/enduser_login_rate_limits.test.js +287 -0
  19. package/lib/cjs/tests/api_tests/enduser_login_rate_limits.test.js.map +1 -0
  20. package/lib/cjs/tests/api_tests/push_forms_to_portal_group_completion.test.d.ts +6 -0
  21. package/lib/cjs/tests/api_tests/push_forms_to_portal_group_completion.test.d.ts.map +1 -0
  22. package/lib/cjs/tests/api_tests/push_forms_to_portal_group_completion.test.js +406 -0
  23. package/lib/cjs/tests/api_tests/push_forms_to_portal_group_completion.test.js.map +1 -0
  24. package/lib/cjs/tests/api_tests/security/F-0001-data-sync-redaction-bypass.test.d.ts +28 -0
  25. package/lib/cjs/tests/api_tests/security/F-0001-data-sync-redaction-bypass.test.d.ts.map +1 -0
  26. package/lib/cjs/tests/api_tests/security/F-0001-data-sync-redaction-bypass.test.js +349 -0
  27. package/lib/cjs/tests/api_tests/security/F-0001-data-sync-redaction-bypass.test.js.map +1 -0
  28. package/lib/cjs/tests/api_tests/security/F-0005-ai-conversations-rbac.test.d.ts +28 -0
  29. package/lib/cjs/tests/api_tests/security/F-0005-ai-conversations-rbac.test.d.ts.map +1 -0
  30. package/lib/cjs/tests/api_tests/security/F-0005-ai-conversations-rbac.test.js +247 -0
  31. package/lib/cjs/tests/api_tests/security/F-0005-ai-conversations-rbac.test.js.map +1 -0
  32. package/lib/cjs/tests/api_tests/security/F-0007-invite-user-enumeration.test.d.ts +29 -0
  33. package/lib/cjs/tests/api_tests/security/F-0007-invite-user-enumeration.test.d.ts.map +1 -0
  34. package/lib/cjs/tests/api_tests/security/F-0007-invite-user-enumeration.test.js +278 -0
  35. package/lib/cjs/tests/api_tests/security/F-0007-invite-user-enumeration.test.js.map +1 -0
  36. package/lib/cjs/tests/api_tests/security/F-0008-handle-incoming-communication-cross-tenant.test.d.ts +24 -0
  37. package/lib/cjs/tests/api_tests/security/F-0008-handle-incoming-communication-cross-tenant.test.d.ts.map +1 -0
  38. package/lib/cjs/tests/api_tests/security/F-0008-handle-incoming-communication-cross-tenant.test.js +201 -0
  39. package/lib/cjs/tests/api_tests/security/F-0008-handle-incoming-communication-cross-tenant.test.js.map +1 -0
  40. package/lib/cjs/tests/api_tests/security/F-0013-sanitize-user-html.test.d.ts +2 -0
  41. package/lib/cjs/tests/api_tests/security/F-0013-sanitize-user-html.test.d.ts.map +1 -0
  42. package/lib/cjs/tests/api_tests/security/F-0013-sanitize-user-html.test.js +148 -0
  43. package/lib/cjs/tests/api_tests/security/F-0013-sanitize-user-html.test.js.map +1 -0
  44. package/lib/cjs/tests/api_tests/security/F-0016-prototype-pollution.test.d.ts +2 -0
  45. package/lib/cjs/tests/api_tests/security/F-0016-prototype-pollution.test.d.ts.map +1 -0
  46. package/lib/cjs/tests/api_tests/security/F-0016-prototype-pollution.test.js +88 -0
  47. package/lib/cjs/tests/api_tests/security/F-0016-prototype-pollution.test.js.map +1 -0
  48. package/lib/cjs/tests/api_tests/set_fields_order_templates.test.d.ts +6 -0
  49. package/lib/cjs/tests/api_tests/set_fields_order_templates.test.d.ts.map +1 -0
  50. package/lib/cjs/tests/api_tests/set_fields_order_templates.test.js +373 -0
  51. package/lib/cjs/tests/api_tests/set_fields_order_templates.test.js.map +1 -0
  52. package/lib/cjs/tests/setup.d.ts.map +1 -1
  53. package/lib/cjs/tests/setup.js +47 -32
  54. package/lib/cjs/tests/setup.js.map +1 -1
  55. package/lib/cjs/tests/tests.d.ts.map +1 -1
  56. package/lib/cjs/tests/tests.js +215 -159
  57. package/lib/cjs/tests/tests.js.map +1 -1
  58. package/lib/esm/sdk.d.ts +9 -0
  59. package/lib/esm/sdk.d.ts.map +1 -1
  60. package/lib/esm/sdk.js +3 -0
  61. package/lib/esm/sdk.js.map +1 -1
  62. package/lib/esm/tests/api_tests/account_switcher.test.d.ts.map +1 -1
  63. package/lib/esm/tests/api_tests/account_switcher.test.js +1702 -305
  64. package/lib/esm/tests/api_tests/account_switcher.test.js.map +1 -1
  65. package/lib/esm/tests/api_tests/calendar_event_webhook_template.test.d.ts +6 -0
  66. package/lib/esm/tests/api_tests/calendar_event_webhook_template.test.d.ts.map +1 -0
  67. package/lib/esm/tests/api_tests/calendar_event_webhook_template.test.js +333 -0
  68. package/lib/esm/tests/api_tests/calendar_event_webhook_template.test.js.map +1 -0
  69. package/lib/esm/tests/api_tests/enduser_login.test.d.ts +6 -0
  70. package/lib/esm/tests/api_tests/enduser_login.test.d.ts.map +1 -0
  71. package/lib/esm/tests/api_tests/enduser_login.test.js +308 -0
  72. package/lib/esm/tests/api_tests/enduser_login.test.js.map +1 -0
  73. package/lib/esm/tests/api_tests/enduser_login_phi_disclosure.test.d.ts +6 -0
  74. package/lib/esm/tests/api_tests/enduser_login_phi_disclosure.test.d.ts.map +1 -0
  75. package/lib/esm/tests/api_tests/enduser_login_phi_disclosure.test.js +268 -0
  76. package/lib/esm/tests/api_tests/enduser_login_phi_disclosure.test.js.map +1 -0
  77. package/lib/esm/tests/api_tests/enduser_login_rate_limits.test.d.ts +6 -0
  78. package/lib/esm/tests/api_tests/enduser_login_rate_limits.test.d.ts.map +1 -0
  79. package/lib/esm/tests/api_tests/enduser_login_rate_limits.test.js +280 -0
  80. package/lib/esm/tests/api_tests/enduser_login_rate_limits.test.js.map +1 -0
  81. package/lib/esm/tests/api_tests/push_forms_to_portal_group_completion.test.d.ts +6 -0
  82. package/lib/esm/tests/api_tests/push_forms_to_portal_group_completion.test.d.ts.map +1 -0
  83. package/lib/esm/tests/api_tests/push_forms_to_portal_group_completion.test.js +402 -0
  84. package/lib/esm/tests/api_tests/push_forms_to_portal_group_completion.test.js.map +1 -0
  85. package/lib/esm/tests/api_tests/security/F-0001-data-sync-redaction-bypass.test.d.ts +28 -0
  86. package/lib/esm/tests/api_tests/security/F-0001-data-sync-redaction-bypass.test.d.ts.map +1 -0
  87. package/lib/esm/tests/api_tests/security/F-0001-data-sync-redaction-bypass.test.js +345 -0
  88. package/lib/esm/tests/api_tests/security/F-0001-data-sync-redaction-bypass.test.js.map +1 -0
  89. package/lib/esm/tests/api_tests/security/F-0005-ai-conversations-rbac.test.d.ts +28 -0
  90. package/lib/esm/tests/api_tests/security/F-0005-ai-conversations-rbac.test.d.ts.map +1 -0
  91. package/lib/esm/tests/api_tests/security/F-0005-ai-conversations-rbac.test.js +243 -0
  92. package/lib/esm/tests/api_tests/security/F-0005-ai-conversations-rbac.test.js.map +1 -0
  93. package/lib/esm/tests/api_tests/security/F-0007-invite-user-enumeration.test.d.ts +29 -0
  94. package/lib/esm/tests/api_tests/security/F-0007-invite-user-enumeration.test.d.ts.map +1 -0
  95. package/lib/esm/tests/api_tests/security/F-0007-invite-user-enumeration.test.js +271 -0
  96. package/lib/esm/tests/api_tests/security/F-0007-invite-user-enumeration.test.js.map +1 -0
  97. package/lib/esm/tests/api_tests/security/F-0008-handle-incoming-communication-cross-tenant.test.d.ts +24 -0
  98. package/lib/esm/tests/api_tests/security/F-0008-handle-incoming-communication-cross-tenant.test.d.ts.map +1 -0
  99. package/lib/esm/tests/api_tests/security/F-0008-handle-incoming-communication-cross-tenant.test.js +194 -0
  100. package/lib/esm/tests/api_tests/security/F-0008-handle-incoming-communication-cross-tenant.test.js.map +1 -0
  101. package/lib/esm/tests/api_tests/security/F-0013-sanitize-user-html.test.d.ts +2 -0
  102. package/lib/esm/tests/api_tests/security/F-0013-sanitize-user-html.test.d.ts.map +1 -0
  103. package/lib/esm/tests/api_tests/security/F-0013-sanitize-user-html.test.js +144 -0
  104. package/lib/esm/tests/api_tests/security/F-0013-sanitize-user-html.test.js.map +1 -0
  105. package/lib/esm/tests/api_tests/security/F-0016-prototype-pollution.test.d.ts +2 -0
  106. package/lib/esm/tests/api_tests/security/F-0016-prototype-pollution.test.d.ts.map +1 -0
  107. package/lib/esm/tests/api_tests/security/F-0016-prototype-pollution.test.js +84 -0
  108. package/lib/esm/tests/api_tests/security/F-0016-prototype-pollution.test.js.map +1 -0
  109. package/lib/esm/tests/api_tests/set_fields_order_templates.test.d.ts +6 -0
  110. package/lib/esm/tests/api_tests/set_fields_order_templates.test.d.ts.map +1 -0
  111. package/lib/esm/tests/api_tests/set_fields_order_templates.test.js +369 -0
  112. package/lib/esm/tests/api_tests/set_fields_order_templates.test.js.map +1 -0
  113. package/lib/esm/tests/setup.d.ts.map +1 -1
  114. package/lib/esm/tests/setup.js +47 -32
  115. package/lib/esm/tests/setup.js.map +1 -1
  116. package/lib/esm/tests/tests.d.ts.map +1 -1
  117. package/lib/esm/tests/tests.js +215 -159
  118. package/lib/esm/tests/tests.js.map +1 -1
  119. package/lib/tsconfig.tsbuildinfo +1 -1
  120. package/package.json +10 -10
  121. package/src/sdk.ts +12 -0
  122. package/src/tests/api_tests/account_switcher.test.ts +1283 -0
  123. package/src/tests/api_tests/calendar_event_webhook_template.test.ts +204 -0
  124. package/src/tests/api_tests/enduser_login.test.ts +215 -0
  125. package/src/tests/api_tests/enduser_login_rate_limits.test.ts +178 -0
  126. package/src/tests/api_tests/push_forms_to_portal_group_completion.test.ts +223 -0
  127. package/src/tests/api_tests/security/F-0001-data-sync-redaction-bypass.test.ts +236 -0
  128. package/src/tests/api_tests/security/F-0005-ai-conversations-rbac.test.ts +154 -0
  129. package/src/tests/api_tests/security/F-0007-invite-user-enumeration.test.ts +198 -0
  130. package/src/tests/api_tests/security/F-0008-handle-incoming-communication-cross-tenant.test.ts +130 -0
  131. package/src/tests/api_tests/security/F-0013-sanitize-user-html.test.ts +109 -0
  132. package/src/tests/api_tests/security/F-0016-prototype-pollution.test.ts +50 -0
  133. package/src/tests/api_tests/set_fields_order_templates.test.ts +258 -0
  134. package/src/tests/setup.ts +8 -1
  135. package/src/tests/tests.ts +35 -5
  136. package/test_generated.pdf +0 -0
@@ -0,0 +1,280 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ 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;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ require('source-map-support').install();
38
+ import axios from "axios";
39
+ import { Session } from "../../sdk";
40
+ import { async_test, log_header, } from "@tellescope/testing";
41
+ import { setup_tests } from "../setup";
42
+ var host = process.env.API_URL || 'http://localhost:8080';
43
+ // Per-IP rate limits applied to enduser public endpoints:
44
+ // POST /v1/login-enduser 20 / min, 100 / hour
45
+ // POST /v1/begin-enduser-login-flow 10 / min, 50 / hour
46
+ // POST /v1/endusers/send-otp-code 5 / min, 30 / hour
47
+ // Plus a per-identifier limit on begin_login_flow: 5 / 10 min per email|phone.
48
+ var post = function (path, body) { return __awaiter(void 0, void 0, void 0, function () {
49
+ var res, err_1;
50
+ var _a, _b;
51
+ return __generator(this, function (_c) {
52
+ switch (_c.label) {
53
+ case 0:
54
+ _c.trys.push([0, 2, , 3]);
55
+ return [4 /*yield*/, axios.post("".concat(host).concat(path), body, { validateStatus: function () { return true; } })];
56
+ case 1:
57
+ res = _c.sent();
58
+ return [2 /*return*/, { status: res.status, data: res.data }];
59
+ case 2:
60
+ err_1 = _c.sent();
61
+ return [2 /*return*/, { status: (_a = err_1 === null || err_1 === void 0 ? void 0 : err_1.response) === null || _a === void 0 ? void 0 : _a.status, data: (_b = err_1 === null || err_1 === void 0 ? void 0 : err_1.response) === null || _b === void 0 ? void 0 : _b.data }];
62
+ case 3: return [2 /*return*/];
63
+ }
64
+ });
65
+ }); };
66
+ var fire_until_429 = function (cap, send) { return __awaiter(void 0, void 0, void 0, function () {
67
+ var triggeredAt, i, status_1;
68
+ return __generator(this, function (_a) {
69
+ switch (_a.label) {
70
+ case 0:
71
+ triggeredAt = -1;
72
+ i = 0;
73
+ _a.label = 1;
74
+ case 1:
75
+ if (!(i < cap + 5)) return [3 /*break*/, 4];
76
+ return [4 /*yield*/, send(i)];
77
+ case 2:
78
+ status_1 = (_a.sent()).status;
79
+ if (status_1 === 429) {
80
+ triggeredAt = i;
81
+ return [3 /*break*/, 4];
82
+ }
83
+ _a.label = 3;
84
+ case 3:
85
+ i++;
86
+ return [3 /*break*/, 1];
87
+ case 4: return [2 /*return*/, triggeredAt];
88
+ }
89
+ });
90
+ }); };
91
+ export var enduser_login_rate_limits_tests = function (_a) {
92
+ var sdk = _a.sdk, sdkNonAdmin = _a.sdkNonAdmin;
93
+ return __awaiter(void 0, void 0, void 0, function () {
94
+ var businessId, loginTrip, beginIpTrip, fixedEmail, beginIdTrip, fakeToken, sendOtpTrip, tripped, ts, enduser, goodLogin_1, goodLoginRetry_1;
95
+ return __generator(this, function (_b) {
96
+ switch (_b.label) {
97
+ case 0:
98
+ log_header("Enduser Login Rate Limit Tests");
99
+ businessId = sdk.userInfo.businessId;
100
+ // Ensure throttled_events from prior tests don't bleed in.
101
+ return [4 /*yield*/, sdk.reset_db()
102
+ // ---- /v1/login-enduser per-IP cap (20/min) ----
103
+ // Bogus emails ensure we never reach the actual DB lookup / login work.
104
+ ];
105
+ case 1:
106
+ // Ensure throttled_events from prior tests don't bleed in.
107
+ _b.sent();
108
+ return [4 /*yield*/, fire_until_429(20, function (i) { return post('/v1/login-enduser', {
109
+ email: "rl-login-".concat(Date.now(), "-").concat(i, "@tellescope.com"),
110
+ password: 'NotARealPassword!2025',
111
+ businessId: businessId,
112
+ }); })];
113
+ case 2:
114
+ loginTrip = _b.sent();
115
+ return [4 /*yield*/, async_test('login per-IP throttle trips within first 21 requests', function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
116
+ return [2 /*return*/, (loginTrip >= 0 && loginTrip <= 20) ? 'tripped' : "not-tripped:".concat(loginTrip)];
117
+ }); }); }, { expectedResult: 'tripped' })];
118
+ case 3:
119
+ _b.sent();
120
+ return [4 /*yield*/, sdk.reset_db()
121
+ // ---- /v1/begin-enduser-login-flow per-IP cap (10/min) ----
122
+ // Use distinct emails so the per-identifier limit (5/10min) does NOT trip first;
123
+ // we want the IP cap to be the first thing to fire.
124
+ ];
125
+ case 4:
126
+ _b.sent();
127
+ return [4 /*yield*/, fire_until_429(10, function (i) { return post('/v1/begin-enduser-login-flow', {
128
+ email: "rl-begin-ip-".concat(Date.now(), "-").concat(i, "@tellescope.com"),
129
+ businessId: businessId,
130
+ }); })];
131
+ case 5:
132
+ beginIpTrip = _b.sent();
133
+ return [4 /*yield*/, async_test('begin_login_flow per-IP throttle trips within first 11 requests', function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
134
+ return [2 /*return*/, (beginIpTrip >= 0 && beginIpTrip <= 10) ? 'tripped' : "not-tripped:".concat(beginIpTrip)];
135
+ }); }); }, { expectedResult: 'tripped' })];
136
+ case 6:
137
+ _b.sent();
138
+ return [4 /*yield*/, sdk.reset_db()
139
+ // ---- /v1/begin-enduser-login-flow per-identifier cap (5 / 10 min per email) ----
140
+ // Hit a single email below the per-IP cap.
141
+ ];
142
+ case 7:
143
+ _b.sent();
144
+ fixedEmail = "rl-begin-id-".concat(Date.now(), "@tellescope.com");
145
+ return [4 /*yield*/, fire_until_429(5, function () { return post('/v1/begin-enduser-login-flow', {
146
+ email: fixedEmail,
147
+ businessId: businessId,
148
+ }); })];
149
+ case 8:
150
+ beginIdTrip = _b.sent();
151
+ return [4 /*yield*/, async_test('begin_login_flow per-identifier throttle trips within first 6 requests', function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
152
+ return [2 /*return*/, (beginIdTrip >= 0 && beginIdTrip <= 5) ? 'tripped' : "not-tripped:".concat(beginIdTrip)];
153
+ }); }); }, { expectedResult: 'tripped' })];
154
+ case 9:
155
+ _b.sent();
156
+ return [4 /*yield*/, sdk.reset_db()
157
+ // ---- /v1/endusers/send-otp-code per-IP cap (5/min) ----
158
+ // Use a bogus JWT-shaped token so we trip the IP guard first (it runs before any DB work).
159
+ ];
160
+ case 10:
161
+ _b.sent();
162
+ fakeToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9.sig';
163
+ return [4 /*yield*/, fire_until_429(5, function () { return post('/v1/endusers/send-otp-code', {
164
+ token: fakeToken,
165
+ method: 'email',
166
+ }); })];
167
+ case 11:
168
+ sendOtpTrip = _b.sent();
169
+ return [4 /*yield*/, async_test('send_otp per-IP throttle trips within first 6 requests', function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
170
+ return [2 /*return*/, (sendOtpTrip >= 0 && sendOtpTrip <= 5) ? 'tripped' : "not-tripped:".concat(sendOtpTrip)];
171
+ }); }); }, { expectedResult: 'tripped' })
172
+ // Confirm 429 response does not leak the keying strategy (no mention of "ip" or "address").
173
+ ];
174
+ case 12:
175
+ _b.sent();
176
+ return [4 /*yield*/, post('/v1/endusers/send-otp-code', { token: fakeToken, method: 'email' })];
177
+ case 13:
178
+ tripped = _b.sent();
179
+ return [4 /*yield*/, async_test('429 response does not mention "ip" or "address"', function () { return __awaiter(void 0, void 0, void 0, function () {
180
+ var msg;
181
+ var _a, _b;
182
+ return __generator(this, function (_c) {
183
+ msg = ((_b = (_a = tripped.data) === null || _a === void 0 ? void 0 : _a.message) !== null && _b !== void 0 ? _b : '').toLowerCase();
184
+ return [2 /*return*/, (msg.includes('ip') || msg.includes('address')) ? 'leaked' : 'safe'];
185
+ });
186
+ }); }, { expectedResult: 'safe' })
187
+ // ---- Legitimate-login regression: a single successful login should still go through ----
188
+ // Reset state, then create a real enduser with a password and confirm one login succeeds.
189
+ ];
190
+ case 14:
191
+ _b.sent();
192
+ // ---- Legitimate-login regression: a single successful login should still go through ----
193
+ // Reset state, then create a real enduser with a password and confirm one login succeeds.
194
+ return [4 /*yield*/, sdk.reset_db()];
195
+ case 15:
196
+ // ---- Legitimate-login regression: a single successful login should still go through ----
197
+ // Reset state, then create a real enduser with a password and confirm one login succeeds.
198
+ _b.sent();
199
+ ts = Date.now();
200
+ return [4 /*yield*/, sdk.api.endusers.createOne({
201
+ fname: 'RateLimitOk', lname: 'Enduser',
202
+ email: "rl-legit-".concat(ts, "@tellescope.com"),
203
+ })];
204
+ case 16:
205
+ enduser = _b.sent();
206
+ _b.label = 17;
207
+ case 17:
208
+ _b.trys.push([17, , 23, 26]);
209
+ return [4 /*yield*/, sdk.api.endusers.set_password({ id: enduser.id, password: 'CorrectPassword123!' })];
210
+ case 18:
211
+ _b.sent();
212
+ return [4 /*yield*/, post('/v1/login-enduser', {
213
+ email: enduser.email,
214
+ password: 'CorrectPassword123!',
215
+ businessId: businessId,
216
+ })];
217
+ case 19:
218
+ goodLogin_1 = _b.sent();
219
+ return [4 /*yield*/, async_test('legitimate login still succeeds (returns authToken, not 429)', function () { return __awaiter(void 0, void 0, void 0, function () { var _a; return __generator(this, function (_b) {
220
+ return [2 /*return*/, goodLogin_1.status === 200 && !!((_a = goodLogin_1.data) === null || _a === void 0 ? void 0 : _a.authToken) ? 'ok' : "failed:".concat(goodLogin_1.status)];
221
+ }); }); }, { expectedResult: 'ok' })
222
+ // A subsequent successful login by the same user/IP should also succeed —
223
+ // a single legitimate user retrying must not trip the per-IP cap.
224
+ ];
225
+ case 20:
226
+ _b.sent();
227
+ return [4 /*yield*/, post('/v1/login-enduser', {
228
+ email: enduser.email,
229
+ password: 'CorrectPassword123!',
230
+ businessId: businessId,
231
+ })];
232
+ case 21:
233
+ goodLoginRetry_1 = _b.sent();
234
+ return [4 /*yield*/, async_test('legitimate login retry still succeeds', function () { return __awaiter(void 0, void 0, void 0, function () { var _a; return __generator(this, function (_b) {
235
+ return [2 /*return*/, goodLoginRetry_1.status === 200 && !!((_a = goodLoginRetry_1.data) === null || _a === void 0 ? void 0 : _a.authToken) ? 'ok' : "failed:".concat(goodLoginRetry_1.status)];
236
+ }); }); }, { expectedResult: 'ok' })];
237
+ case 22:
238
+ _b.sent();
239
+ return [3 /*break*/, 26];
240
+ case 23: return [4 /*yield*/, sdk.api.endusers.deleteOne(enduser.id).catch(function () { return null; })];
241
+ case 24:
242
+ _b.sent();
243
+ return [4 /*yield*/, sdk.reset_db().catch(function () { return null; })];
244
+ case 25:
245
+ _b.sent();
246
+ return [7 /*endfinally*/];
247
+ case 26: return [2 /*return*/];
248
+ }
249
+ });
250
+ });
251
+ };
252
+ // Allow running this test file independently
253
+ if (require.main === module) {
254
+ console.log("\uD83C\uDF10 Using API URL: ".concat(host));
255
+ var sdk_1 = new Session({ host: host });
256
+ var sdkNonAdmin_1 = new Session({ host: host });
257
+ var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
258
+ return __generator(this, function (_a) {
259
+ switch (_a.label) {
260
+ case 0: return [4 /*yield*/, setup_tests(sdk_1, sdkNonAdmin_1)];
261
+ case 1:
262
+ _a.sent();
263
+ return [4 /*yield*/, enduser_login_rate_limits_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
264
+ case 2:
265
+ _a.sent();
266
+ return [2 /*return*/];
267
+ }
268
+ });
269
+ }); };
270
+ runTests()
271
+ .then(function () {
272
+ console.log("✅ Enduser login rate limit test suite completed successfully");
273
+ process.exit(0);
274
+ })
275
+ .catch(function (error) {
276
+ console.error("❌ Enduser login rate limit test suite failed:", error);
277
+ process.exit(1);
278
+ });
279
+ }
280
+ //# sourceMappingURL=enduser_login_rate_limits.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enduser_login_rate_limits.test.js","sourceRoot":"","sources":["../../../../src/tests/api_tests/enduser_login_rate_limits.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Session } from "../../sdk";
2
+ export declare const push_forms_to_portal_group_completion_tests: ({ sdk, sdkNonAdmin }: {
3
+ sdk: Session;
4
+ sdkNonAdmin: Session;
5
+ }) => Promise<void>;
6
+ //# sourceMappingURL=push_forms_to_portal_group_completion.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push_forms_to_portal_group_completion.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/api_tests/push_forms_to_portal_group_completion.test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAkB,MAAM,WAAW,CAAA;AAuBnD,eAAO,MAAM,2CAA2C;SAAwC,OAAO;iBAAe,OAAO;mBAgL5H,CAAA"}