@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,144 @@
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
+ import { sanitize_user_html } from "@tellescope/utilities";
38
+ // Regression test for F-0013 / F-0014 (pattern 06 — XSS via dangerouslySetInnerHTML).
39
+ // sanitize_user_html is the canonical render-time sanitizer that replaced remove_script_tags
40
+ // at every dangerouslySetInnerHTML sink. This asserts it neutralizes XSS vectors (incl. encoded /
41
+ // whitespace / mixed-case / iframe-srcdoc bypass variants) while preserving legitimate
42
+ // customization HTML (tables, headings, lists, links, images, inline styles).
43
+ //
44
+ // Pure-function test — no Session needed. Runs as part of the main suite and standalone:
45
+ // ./build_cjs.sh && cd packages/public/sdk && node -r dotenv/config lib/cjs/tests/api_tests/security/F-0013-sanitize-user-html.test.js
46
+ var fail = function (msg) { throw new Error(msg); };
47
+ var has_no_executable_vector = function (out) {
48
+ var o = out.toLowerCase();
49
+ // A handler smuggled into an attribute VALUE (e.g. title="&lt;img onerror=...&gt;") is inert
50
+ // text — strip quoted values before checking for *live* on*= attributes to avoid false positives.
51
+ var withoutValues = o.replace(/"[^"]*"/g, '""').replace(/'[^']*'/g, "''");
52
+ return !/\son[a-z]+\s*=/.test(withoutValues) // no live on*= event-handler attribute
53
+ && !o.includes('javascript:') // dropped schemes never appear in safe output
54
+ && !o.includes('vbscript:')
55
+ && !o.includes('<script') // literal dangerous tags (encoded &lt;script is fine)
56
+ && !o.includes('<iframe')
57
+ && !o.includes('<svg')
58
+ && !o.includes('<math')
59
+ && !o.includes('<object')
60
+ && !o.includes('<embed')
61
+ && !o.includes('<form')
62
+ && !o.includes('<noscript')
63
+ && !o.includes('<template');
64
+ };
65
+ export var sanitize_user_html_xss_tests = function () { return __awaiter(void 0, void 0, void 0, function () {
66
+ var xssPayloads, _i, xssPayloads_1, _a, name_1, payload, out, clobber, heading, table, list, link, img, dataimg, fmt, mixed;
67
+ return __generator(this, function (_b) {
68
+ console.log("Running F-0013/F-0014 sanitize_user_html XSS regression tests");
69
+ xssPayloads = [
70
+ ['img onerror', "<img src=x onerror=\"alert(document.domain)\">"],
71
+ ['svg onload', "<svg onload=\"alert(1)\"></svg>"],
72
+ ['svg animate onbegin', "<svg><animate onbegin=\"alert(1)\" attributeName=\"x\" dur=\"1s\"></svg>"],
73
+ ['details ontoggle', "<details open ontoggle=\"alert(1)\"></details>"],
74
+ ['input onfocus autofocus', "<input autofocus onfocus=\"alert(1)\">"],
75
+ ['body onpageshow', "<body onpageshow=\"alert(1)\">"],
76
+ ['a javascript scheme', "<a href=\"javascript:alert(1)\">x</a>"],
77
+ ['a javascript entity-encoded', "<a href=\"jav&#x09;ascript:alert(1)\">x</a>"],
78
+ ['iframe javascript src', "<iframe src=\"javascript:alert(1)\"></iframe>"],
79
+ ['iframe srcdoc nested', "<iframe srcdoc=\"<img src=x onerror=alert(1)>\"></iframe>"],
80
+ ['script tag', "<script>alert(1)</script>"],
81
+ ['onerror newline before =', "<img src=x onerror\n=\"alert(1)\">"],
82
+ ['onerror mixed case', "<IMG SRC=x OnErRoR=\"alert(1)\">"],
83
+ ['marquee onstart', "<marquee onstart=\"alert(1)\">x</marquee>"],
84
+ // mutation / namespace confusion — svg/math/noscript/template must be stripped
85
+ ['mathml mglyph style mxss', "<math><mtext><table><mglyph><style><!--</style><img src=x onerror=alert(1)>"],
86
+ ['svg foreignObject', "<svg><foreignObject><img src=x onerror=alert(1)></foreignObject></svg>"],
87
+ ['noscript context confusion', "<noscript><p title=\"</noscript><img src=x onerror=alert(1)>\">"],
88
+ ['template content', "<template><img src=x onerror=alert(1)></template>"],
89
+ // comment / CDATA confusion
90
+ ['comment confusion', "<!--><img src=x onerror=alert(1)>-->"],
91
+ ['cdata confusion', "<![CDATA[<img src=x onerror=alert(1)>]]>"],
92
+ // markup smuggled inside an attribute value must stay inert
93
+ ['markup inside attr value', "<img src=\"x\" alt=\"<script>alert(1)</script>\">"],
94
+ // protocol obfuscation
95
+ ['vbscript scheme', "<a href=\"vbscript:msgbox(1)\">x</a>"],
96
+ ['data text/html href', "<a href=\"data:text/html,<script>alert(1)</script>\">x</a>"],
97
+ ['javascript decimal entity', "<a href=\"&#74;avascript:alert(1)\">x</a>"],
98
+ ['javascript newline entity', "<a href=\"jav&#x0A;ascript:alert(1)\">x</a>"],
99
+ ];
100
+ for (_i = 0, xssPayloads_1 = xssPayloads; _i < xssPayloads_1.length; _i++) {
101
+ _a = xssPayloads_1[_i], name_1 = _a[0], payload = _a[1];
102
+ out = sanitize_user_html(payload);
103
+ if (!has_no_executable_vector(out))
104
+ fail("XSS not neutralized [".concat(name_1, "] -> ").concat(out));
105
+ }
106
+ clobber = sanitize_user_html("<a id=\"x\" name=\"getElementById\">link</a><img name=\"y\">");
107
+ if (/\b(id|name)\s*=/.test(clobber))
108
+ fail("id/name not stripped (DOM clobbering): ".concat(clobber));
109
+ heading = sanitize_user_html("<h1>Welcome</h1><h3 style=\"color:#333\">Sub</h3>");
110
+ if (!(heading.includes('<h1>') && heading.includes('<h3') && heading.toLowerCase().includes('color')))
111
+ fail("headings/style stripped: ".concat(heading));
112
+ table = sanitize_user_html("<table><thead><tr><th>H</th></tr></thead><tbody><tr><td style=\"padding:4px\" colspan=\"2\">cell</td></tr></tbody></table>");
113
+ if (!(table.includes('<table') && table.includes('<td') && table.includes('colspan')))
114
+ fail("table stripped: ".concat(table));
115
+ list = sanitize_user_html("<ul><li>a</li></ul><ol start=\"3\"><li>c</li></ol>");
116
+ if (!(list.includes('<ul') && list.includes('<li') && list.includes('<ol')))
117
+ fail("list stripped: ".concat(list));
118
+ link = sanitize_user_html("<a href=\"https://example.com\">link</a>");
119
+ if (!link.includes('href="https://example.com"'))
120
+ fail("safe link stripped: ".concat(link));
121
+ if (!link.toLowerCase().includes('noopener'))
122
+ fail("external link not hardened: ".concat(link));
123
+ img = sanitize_user_html("<img src=\"https://cdn.example.com/a.png\" alt=\"pic\" width=\"200\">");
124
+ if (!(img.includes('src="https://cdn.example.com/a.png"') && img.includes('alt="pic"')))
125
+ fail("http image stripped: ".concat(img));
126
+ dataimg = sanitize_user_html("<img src=\"data:image/png;base64,iVBORw0KGgo=\">");
127
+ if (!dataimg.includes('data:image/png'))
128
+ fail("data: image stripped: ".concat(dataimg));
129
+ fmt = sanitize_user_html("<p><strong>b</strong> <em>i</em> <span style=\"font-size:14px\">s</span></p><blockquote>q</blockquote>");
130
+ if (!(fmt.includes('<strong>') && fmt.includes('<span') && fmt.toLowerCase().includes('font-size')))
131
+ fail("formatting stripped: ".concat(fmt));
132
+ mixed = sanitize_user_html("<p>Hello <b>name</b></p><img src=x onerror=\"steal()\">");
133
+ if (!(mixed.includes('<b>name</b>') && !/\son[a-z]+\s*=/.test(mixed.toLowerCase())))
134
+ fail("mixed content not handled: ".concat(mixed));
135
+ console.log("✅ F-0013/F-0014 sanitize_user_html XSS regression tests passed");
136
+ return [2 /*return*/];
137
+ });
138
+ }); };
139
+ if (require.main === module) {
140
+ sanitize_user_html_xss_tests()
141
+ .then(function () { console.log("✅ suite completed"); process.exit(0); })
142
+ .catch(function (err) { console.error("❌ suite failed:", err); process.exit(1); });
143
+ }
144
+ //# sourceMappingURL=F-0013-sanitize-user-html.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"F-0013-sanitize-user-html.test.js","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/F-0013-sanitize-user-html.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const prototype_pollution_tests: () => Promise<void>;
2
+ //# sourceMappingURL=F-0016-prototype-pollution.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"F-0016-prototype-pollution.test.d.ts","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/F-0016-prototype-pollution.test.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,yBAAyB,qBAgCrC,CAAA"}
@@ -0,0 +1,84 @@
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
+ import { add_value_for_dotted_key } from "@tellescope/utilities";
38
+ // Regression test for F-0016 (pattern 17 — prototype pollution).
39
+ // add_value_for_dotted_key must NOT write through __proto__/constructor/prototype path segments
40
+ // (which would pollute Object.prototype process-wide), while still performing legitimate dotted assignment.
41
+ //
42
+ // Pure-function test — no Session needed. Runs in the main suite and standalone:
43
+ // ./build_cjs.sh && cd packages/public/sdk && node -r dotenv/config lib/cjs/tests/api_tests/security/F-0016-prototype-pollution.test.js
44
+ var fail = function (msg) { throw new Error(msg); };
45
+ export var prototype_pollution_tests = function () { return __awaiter(void 0, void 0, void 0, function () {
46
+ var leakedA, leakedB, leakedC, obj, flat;
47
+ return __generator(this, function (_a) {
48
+ console.log("Running F-0016 prototype-pollution regression tests");
49
+ // 1. __proto__ path must not pollute Object.prototype
50
+ add_value_for_dotted_key({ insurance: {} }, 'insurance.__proto__.__pp_a__', 'polluted');
51
+ leakedA = {}.__pp_a__;
52
+ delete Object.prototype.__pp_a__; // clean up regardless, so a failure here can't contaminate the rest of the suite
53
+ if (leakedA !== undefined)
54
+ fail('Object.prototype polluted via __proto__ path');
55
+ // 2. constructor.prototype path must not pollute
56
+ add_value_for_dotted_key({ insurance: {} }, 'insurance.constructor.prototype.__pp_b__', 'polluted');
57
+ leakedB = {}.__pp_b__;
58
+ delete Object.prototype.__pp_b__;
59
+ if (leakedB !== undefined)
60
+ fail('Object.prototype polluted via constructor.prototype path');
61
+ // 3. a leading __proto__ segment must not pollute either
62
+ add_value_for_dotted_key({}, '__proto__.__pp_c__', 'polluted');
63
+ leakedC = {}.__pp_c__;
64
+ delete Object.prototype.__pp_c__;
65
+ if (leakedC !== undefined)
66
+ fail('Object.prototype polluted via leading __proto__ segment');
67
+ obj = { a: { b: {} } };
68
+ add_value_for_dotted_key(obj, 'a.b.c', 42);
69
+ if (obj.a.b.c !== 42)
70
+ fail('legitimate dotted assignment broke');
71
+ flat = {};
72
+ add_value_for_dotted_key(flat, 'name', 'ok');
73
+ if (flat.name !== 'ok')
74
+ fail('single-key assignment broke');
75
+ console.log("✅ F-0016 prototype-pollution regression tests passed");
76
+ return [2 /*return*/];
77
+ });
78
+ }); };
79
+ if (require.main === module) {
80
+ prototype_pollution_tests()
81
+ .then(function () { console.log("✅ suite completed"); process.exit(0); })
82
+ .catch(function (err) { console.error("❌ suite failed:", err); process.exit(1); });
83
+ }
84
+ //# sourceMappingURL=F-0016-prototype-pollution.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"F-0016-prototype-pollution.test.js","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/F-0016-prototype-pollution.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAEhE,iEAAiE;AACjE,gGAAgG;AAChG,4GAA4G;AAC5G,EAAE;AACF,iFAAiF;AACjF,0IAA0I;AAE1I,IAAM,IAAI,GAAG,UAAC,GAAW,IAAO,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAA,CAAC,CAAC,CAAA;AAEtD,MAAM,CAAC,IAAM,yBAAyB,GAAG;;;QACvC,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAA;QAElE,sDAAsD;QACtD,wBAAwB,CAAC,EAAE,SAAS,EAAE,EAAE,EAAS,EAAE,8BAA8B,EAAE,UAAU,CAAC,CAAA;QACxF,OAAO,GAAI,EAAU,CAAC,QAAQ,CAAA;QACpC,OAAQ,MAAM,CAAC,SAAiB,CAAC,QAAQ,CAAA,CAAC,iFAAiF;QAC3H,IAAI,OAAO,KAAK,SAAS;YAAE,IAAI,CAAC,8CAA8C,CAAC,CAAA;QAE/E,iDAAiD;QACjD,wBAAwB,CAAC,EAAE,SAAS,EAAE,EAAE,EAAS,EAAE,0CAA0C,EAAE,UAAU,CAAC,CAAA;QACpG,OAAO,GAAI,EAAU,CAAC,QAAQ,CAAA;QACpC,OAAQ,MAAM,CAAC,SAAiB,CAAC,QAAQ,CAAA;QACzC,IAAI,OAAO,KAAK,SAAS;YAAE,IAAI,CAAC,0DAA0D,CAAC,CAAA;QAE3F,yDAAyD;QACzD,wBAAwB,CAAC,EAAS,EAAE,oBAAoB,EAAE,UAAU,CAAC,CAAA;QAC/D,OAAO,GAAI,EAAU,CAAC,QAAQ,CAAA;QACpC,OAAQ,MAAM,CAAC,SAAiB,CAAC,QAAQ,CAAA;QACzC,IAAI,OAAO,KAAK,SAAS;YAAE,IAAI,CAAC,yDAAyD,CAAC,CAAA;QAGpF,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAS,CAAA;QACnC,wBAAwB,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;QAC1C,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;YAAE,IAAI,CAAC,oCAAoC,CAAC,CAAA;QAG1D,IAAI,GAAG,EAAS,CAAA;QACtB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;QAC5C,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;YAAE,IAAI,CAAC,6BAA6B,CAAC,CAAA;QAE3D,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAA;;;KACpE,CAAA;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE;IAC3B,yBAAyB,EAAE;SACxB,IAAI,CAAC,cAAQ,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC,CAAC;SACjE,KAAK,CAAC,UAAC,GAAG,IAAO,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;CAC9E"}
@@ -0,0 +1,6 @@
1
+ import { Session } from "../../sdk";
2
+ export declare const set_fields_order_templates_tests: ({ sdk, sdkNonAdmin }: {
3
+ sdk: Session;
4
+ sdkNonAdmin: Session;
5
+ }) => Promise<void>;
6
+ //# sourceMappingURL=set_fields_order_templates.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set_fields_order_templates.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/api_tests/set_fields_order_templates.test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAoOnC,eAAO,MAAM,gCAAgC;SACd,OAAO;iBAAe,OAAO;mBAK3D,CAAA"}
@@ -0,0 +1,369 @@
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 { Session } from "../../sdk";
39
+ import { assert, async_test, log_header, wait, } from "@tellescope/testing";
40
+ import { setup_tests } from "../setup";
41
+ var host = process.env.API_URL || 'http://localhost:8080';
42
+ var TRIGGER_TITLE_BLOCK_A = "Order Templates: Block A";
43
+ var TRIGGER_TITLE_BLOCK_B = "Order Templates: Block B";
44
+ var buildSetFieldsAction = function (prefix) { return ({
45
+ type: 'Set Fields',
46
+ info: {
47
+ fields: [
48
+ { name: "".concat(prefix, "_status"), value: '{{order.status}}', type: 'Custom Value' },
49
+ { name: "".concat(prefix, "_tracking"), value: '{{order.tracking}}', type: 'Custom Value' },
50
+ { name: "".concat(prefix, "_carrier"), value: '{{order.carrier}}', type: 'Custom Value' },
51
+ { name: "".concat(prefix, "_sku"), value: '{{order.sku}}', type: 'Custom Value' },
52
+ { name: "".concat(prefix, "_externalId"), value: '{{order.externalId}}', type: 'Custom Value' },
53
+ { name: "".concat(prefix, "_id"), value: '{{order.id}}', type: 'Custom Value' },
54
+ { name: "".concat(prefix, "_protocol"), value: '{{order.protocol}}', type: 'Custom Value' },
55
+ ],
56
+ },
57
+ }); };
58
+ // Block A: Direct EnduserOrder creation path
59
+ var direct_order_creation_block = function (_a) {
60
+ var sdk = _a.sdk;
61
+ return __awaiter(void 0, void 0, void 0, function () {
62
+ var enduser, trigger, createdOrderId, nonMatchingOrderId, order_1, beforeNonMatch, snapshot_1, nonMatching;
63
+ var _b, _c, _d, _e, _f, _g, _h;
64
+ return __generator(this, function (_j) {
65
+ switch (_j.label) {
66
+ case 0:
67
+ log_header("Block A: Direct EnduserOrder creation -> {{order.*}} in Set Fields");
68
+ return [4 /*yield*/, sdk.api.endusers.createOne({})];
69
+ case 1:
70
+ enduser = _j.sent();
71
+ return [4 /*yield*/, sdk.api.automation_triggers.createOne({
72
+ title: TRIGGER_TITLE_BLOCK_A,
73
+ status: 'Active',
74
+ event: { type: 'Order Status Equals', info: { source: 'Beluga', status: 'Shipped' } },
75
+ action: buildSetFieldsAction('pharmacy'),
76
+ })];
77
+ case 2:
78
+ trigger = _j.sent();
79
+ _j.label = 3;
80
+ case 3:
81
+ _j.trys.push([3, , 11, 18]);
82
+ return [4 /*yield*/, sdk.api.enduser_orders.createOne({
83
+ enduserId: enduser.id,
84
+ source: 'Beluga',
85
+ status: 'Shipped',
86
+ title: 'Beluga Pharmacy Order',
87
+ externalId: 'EXT-A-123',
88
+ tracking: '1Z-AAA',
89
+ carrier: 'UPS',
90
+ sku: 'SKU-A',
91
+ protocol: 'wl1',
92
+ })];
93
+ case 4:
94
+ order_1 = _j.sent();
95
+ createdOrderId = order_1.id;
96
+ return [4 /*yield*/, wait(undefined, 250)]; // allow trigger + Set Fields to run
97
+ case 5:
98
+ _j.sent(); // allow trigger + Set Fields to run
99
+ return [4 /*yield*/, async_test("Block A: {{order.*}} templates resolve to literal values", function () { return sdk.api.endusers.getOne(enduser.id); }, { onResult: function (e) {
100
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
101
+ return !!(((_a = e.fields) === null || _a === void 0 ? void 0 : _a.pharmacy_status) === 'Shipped'
102
+ && ((_b = e.fields) === null || _b === void 0 ? void 0 : _b.pharmacy_tracking) === '1Z-AAA'
103
+ && ((_c = e.fields) === null || _c === void 0 ? void 0 : _c.pharmacy_carrier) === 'UPS'
104
+ && ((_d = e.fields) === null || _d === void 0 ? void 0 : _d.pharmacy_sku) === 'SKU-A'
105
+ && ((_e = e.fields) === null || _e === void 0 ? void 0 : _e.pharmacy_externalId) === 'EXT-A-123'
106
+ && ((_f = e.fields) === null || _f === void 0 ? void 0 : _f.pharmacy_protocol) === 'wl1'
107
+ && typeof ((_g = e.fields) === null || _g === void 0 ? void 0 : _g.pharmacy_id) === 'string'
108
+ && ((_h = e.fields) === null || _h === void 0 ? void 0 : _h.pharmacy_id).length > 0
109
+ && ((_j = e.fields) === null || _j === void 0 ? void 0 : _j.pharmacy_id) === order_1.id);
110
+ } })
111
+ // Negative case: status that doesn't match the trigger should NOT alter fields
112
+ ];
113
+ case 6:
114
+ _j.sent();
115
+ return [4 /*yield*/, sdk.api.endusers.getOne(enduser.id)];
116
+ case 7:
117
+ beforeNonMatch = _j.sent();
118
+ snapshot_1 = {
119
+ pharmacy_status: (_b = beforeNonMatch.fields) === null || _b === void 0 ? void 0 : _b.pharmacy_status,
120
+ pharmacy_tracking: (_c = beforeNonMatch.fields) === null || _c === void 0 ? void 0 : _c.pharmacy_tracking,
121
+ pharmacy_carrier: (_d = beforeNonMatch.fields) === null || _d === void 0 ? void 0 : _d.pharmacy_carrier,
122
+ pharmacy_sku: (_e = beforeNonMatch.fields) === null || _e === void 0 ? void 0 : _e.pharmacy_sku,
123
+ pharmacy_externalId: (_f = beforeNonMatch.fields) === null || _f === void 0 ? void 0 : _f.pharmacy_externalId,
124
+ pharmacy_id: (_g = beforeNonMatch.fields) === null || _g === void 0 ? void 0 : _g.pharmacy_id,
125
+ pharmacy_protocol: (_h = beforeNonMatch.fields) === null || _h === void 0 ? void 0 : _h.pharmacy_protocol,
126
+ };
127
+ return [4 /*yield*/, sdk.api.enduser_orders.createOne({
128
+ enduserId: enduser.id,
129
+ source: 'Beluga',
130
+ status: 'In Fulfillment',
131
+ title: 'Beluga Pharmacy Order (other status)',
132
+ externalId: 'EXT-A-NOMATCH',
133
+ tracking: 'NOPE',
134
+ carrier: 'NoCarrier',
135
+ sku: 'SKU-NOPE',
136
+ protocol: 'nope',
137
+ })];
138
+ case 8:
139
+ nonMatching = _j.sent();
140
+ nonMatchingOrderId = nonMatching.id;
141
+ return [4 /*yield*/, wait(undefined, 250)];
142
+ case 9:
143
+ _j.sent();
144
+ return [4 /*yield*/, async_test("Block A: non-matching status leaves fields unchanged", function () { return sdk.api.endusers.getOne(enduser.id); }, { onResult: function (e) {
145
+ var _a, _b, _c, _d, _e, _f, _g;
146
+ return !!(((_a = e.fields) === null || _a === void 0 ? void 0 : _a.pharmacy_status) === snapshot_1.pharmacy_status
147
+ && ((_b = e.fields) === null || _b === void 0 ? void 0 : _b.pharmacy_tracking) === snapshot_1.pharmacy_tracking
148
+ && ((_c = e.fields) === null || _c === void 0 ? void 0 : _c.pharmacy_carrier) === snapshot_1.pharmacy_carrier
149
+ && ((_d = e.fields) === null || _d === void 0 ? void 0 : _d.pharmacy_sku) === snapshot_1.pharmacy_sku
150
+ && ((_e = e.fields) === null || _e === void 0 ? void 0 : _e.pharmacy_externalId) === snapshot_1.pharmacy_externalId
151
+ && ((_f = e.fields) === null || _f === void 0 ? void 0 : _f.pharmacy_id) === snapshot_1.pharmacy_id
152
+ && ((_g = e.fields) === null || _g === void 0 ? void 0 : _g.pharmacy_protocol) === snapshot_1.pharmacy_protocol);
153
+ } })];
154
+ case 10:
155
+ _j.sent();
156
+ return [3 /*break*/, 18];
157
+ case 11:
158
+ if (!createdOrderId) return [3 /*break*/, 13];
159
+ return [4 /*yield*/, sdk.api.enduser_orders.deleteOne(createdOrderId).catch(console.error)];
160
+ case 12:
161
+ _j.sent();
162
+ _j.label = 13;
163
+ case 13:
164
+ if (!nonMatchingOrderId) return [3 /*break*/, 15];
165
+ return [4 /*yield*/, sdk.api.enduser_orders.deleteOne(nonMatchingOrderId).catch(console.error)];
166
+ case 14:
167
+ _j.sent();
168
+ _j.label = 15;
169
+ case 15: return [4 /*yield*/, sdk.api.automation_triggers.deleteOne(trigger.id).catch(console.error)];
170
+ case 16:
171
+ _j.sent();
172
+ return [4 /*yield*/, sdk.api.endusers.deleteOne(enduser.id).catch(console.error)];
173
+ case 17:
174
+ _j.sent();
175
+ return [7 /*endfinally*/];
176
+ case 18: return [2 /*return*/];
177
+ }
178
+ });
179
+ });
180
+ };
181
+ // Block B: Beluga webhook integration path
182
+ var beluga_webhook_block = function (_a) {
183
+ var sdk = _a.sdk;
184
+ return __awaiter(void 0, void 0, void 0, function () {
185
+ var webhookUrl, externalOrderId, enduser, form, formResponse, trigger, deliveredTrigger, shippedRes, deliveredRes, orders, _i, orders_1, o, err_1;
186
+ return __generator(this, function (_b) {
187
+ switch (_b.label) {
188
+ case 0:
189
+ log_header("Block B: Beluga webhook -> {{order.*}} in Set Fields");
190
+ webhookUrl = "".concat(host, "/v1/webhooks/beluga");
191
+ externalOrderId = "EXT-B-".concat(Date.now());
192
+ return [4 /*yield*/, sdk.api.endusers.createOne({})];
193
+ case 1:
194
+ enduser = _b.sent();
195
+ return [4 /*yield*/, sdk.api.forms.createOne({ title: 'Order Templates Beluga Form' })];
196
+ case 2:
197
+ form = _b.sent();
198
+ return [4 /*yield*/, sdk.api.form_responses.createOne({
199
+ formId: form.id,
200
+ enduserId: enduser.id,
201
+ formTitle: form.title,
202
+ })];
203
+ case 3:
204
+ formResponse = _b.sent();
205
+ return [4 /*yield*/, sdk.api.automation_triggers.createOne({
206
+ title: TRIGGER_TITLE_BLOCK_B,
207
+ status: 'Active',
208
+ event: { type: 'Order Status Equals', info: { source: 'Beluga', status: 'Shipped' } },
209
+ action: buildSetFieldsAction('pharmacy'),
210
+ })];
211
+ case 4:
212
+ trigger = _b.sent();
213
+ return [4 /*yield*/, sdk.api.automation_triggers.createOne({
214
+ title: "".concat(TRIGGER_TITLE_BLOCK_B, " (Delivered)"),
215
+ status: 'Active',
216
+ event: { type: 'Order Status Equals', info: { source: 'Beluga', status: 'Delivered' } },
217
+ action: buildSetFieldsAction('pharmacy'),
218
+ })];
219
+ case 5:
220
+ deliveredTrigger = _b.sent();
221
+ _b.label = 6;
222
+ case 6:
223
+ _b.trys.push([6, , 13, 26]);
224
+ return [4 /*yield*/, fetch(webhookUrl, {
225
+ method: 'POST',
226
+ headers: { 'Content-Type': 'application/json' },
227
+ body: JSON.stringify({
228
+ masterId: "tellescope_".concat(formResponse.id),
229
+ event: 'PHARMACY_ORDER_SHIPPED',
230
+ orderId: externalOrderId,
231
+ info: { carrier: 'FedEx', tracking: '7777-BBB' },
232
+ }),
233
+ })];
234
+ case 7:
235
+ shippedRes = _b.sent();
236
+ assert(shippedRes.status === 200, "Beluga webhook (shipped) expected 200, got ".concat(shippedRes.status));
237
+ return [4 /*yield*/, wait(undefined, 250)]; // webhook upsert + trigger + Set Fields
238
+ case 8:
239
+ _b.sent(); // webhook upsert + trigger + Set Fields
240
+ return [4 /*yield*/, async_test("Block B: Beluga PHARMACY_ORDER_SHIPPED resolves {{order.*}} into enduser fields", function () { return sdk.api.endusers.getOne(enduser.id); }, { onResult: function (e) {
241
+ var _a, _b, _c, _d, _e, _f, _g, _h;
242
+ return !!(((_a = e.fields) === null || _a === void 0 ? void 0 : _a.pharmacy_status) === 'Shipped'
243
+ && ((_b = e.fields) === null || _b === void 0 ? void 0 : _b.pharmacy_tracking) === '7777-BBB'
244
+ && ((_c = e.fields) === null || _c === void 0 ? void 0 : _c.pharmacy_carrier) === 'FedEx'
245
+ && ((_d = e.fields) === null || _d === void 0 ? void 0 : _d.pharmacy_externalId) === externalOrderId
246
+ && typeof ((_e = e.fields) === null || _e === void 0 ? void 0 : _e.pharmacy_id) === 'string'
247
+ && ((_f = e.fields) === null || _f === void 0 ? void 0 : _f.pharmacy_id).length > 0
248
+ // Webhook does not set sku/protocol -> default branch in helper -> ''
249
+ && ((_g = e.fields) === null || _g === void 0 ? void 0 : _g.pharmacy_sku) === ''
250
+ && ((_h = e.fields) === null || _h === void 0 ? void 0 : _h.pharmacy_protocol) === '');
251
+ } })
252
+ // Step 2: PHARMACY_ORDER_DELIVERED for the same order
253
+ ];
254
+ case 9:
255
+ _b.sent();
256
+ return [4 /*yield*/, fetch(webhookUrl, {
257
+ method: 'POST',
258
+ headers: { 'Content-Type': 'application/json' },
259
+ body: JSON.stringify({
260
+ masterId: "tellescope_".concat(formResponse.id),
261
+ event: 'PHARMACY_ORDER_DELIVERED',
262
+ orderId: externalOrderId,
263
+ }),
264
+ })];
265
+ case 10:
266
+ deliveredRes = _b.sent();
267
+ assert(deliveredRes.status === 200, "Beluga webhook (delivered) expected 200, got ".concat(deliveredRes.status));
268
+ return [4 /*yield*/, wait(undefined, 250)];
269
+ case 11:
270
+ _b.sent();
271
+ return [4 /*yield*/, async_test("Block B: PHARMACY_ORDER_DELIVERED flips pharmacy_status to 'Delivered'", function () { return sdk.api.endusers.getOne(enduser.id); }, { onResult: function (e) {
272
+ var _a, _b;
273
+ return !!(((_a = e.fields) === null || _a === void 0 ? void 0 : _a.pharmacy_status) === 'Delivered'
274
+ && ((_b = e.fields) === null || _b === void 0 ? void 0 : _b.pharmacy_externalId) === externalOrderId);
275
+ } })];
276
+ case 12:
277
+ _b.sent();
278
+ return [3 /*break*/, 26];
279
+ case 13:
280
+ _b.trys.push([13, 19, , 20]);
281
+ return [4 /*yield*/, sdk.api.enduser_orders.getSome({
282
+ filter: { source: 'Beluga', externalId: externalOrderId },
283
+ })];
284
+ case 14:
285
+ orders = _b.sent();
286
+ _i = 0, orders_1 = orders;
287
+ _b.label = 15;
288
+ case 15:
289
+ if (!(_i < orders_1.length)) return [3 /*break*/, 18];
290
+ o = orders_1[_i];
291
+ return [4 /*yield*/, sdk.api.enduser_orders.deleteOne(o.id).catch(console.error)];
292
+ case 16:
293
+ _b.sent();
294
+ _b.label = 17;
295
+ case 17:
296
+ _i++;
297
+ return [3 /*break*/, 15];
298
+ case 18: return [3 /*break*/, 20];
299
+ case 19:
300
+ err_1 = _b.sent();
301
+ console.error(err_1);
302
+ return [3 /*break*/, 20];
303
+ case 20: return [4 /*yield*/, sdk.api.automation_triggers.deleteOne(trigger.id).catch(console.error)];
304
+ case 21:
305
+ _b.sent();
306
+ return [4 /*yield*/, sdk.api.automation_triggers.deleteOne(deliveredTrigger.id).catch(console.error)];
307
+ case 22:
308
+ _b.sent();
309
+ return [4 /*yield*/, sdk.api.form_responses.deleteOne(formResponse.id).catch(console.error)];
310
+ case 23:
311
+ _b.sent();
312
+ return [4 /*yield*/, sdk.api.forms.deleteOne(form.id).catch(console.error)];
313
+ case 24:
314
+ _b.sent();
315
+ return [4 /*yield*/, sdk.api.endusers.deleteOne(enduser.id).catch(console.error)];
316
+ case 25:
317
+ _b.sent();
318
+ return [7 /*endfinally*/];
319
+ case 26: return [2 /*return*/];
320
+ }
321
+ });
322
+ });
323
+ };
324
+ export var set_fields_order_templates_tests = function (_a) {
325
+ var sdk = _a.sdk, sdkNonAdmin = _a.sdkNonAdmin;
326
+ return __awaiter(void 0, void 0, void 0, function () {
327
+ return __generator(this, function (_b) {
328
+ switch (_b.label) {
329
+ case 0:
330
+ log_header("Set Fields: {{order.*}} template resolution");
331
+ return [4 /*yield*/, direct_order_creation_block({ sdk: sdk })];
332
+ case 1:
333
+ _b.sent();
334
+ return [4 /*yield*/, beluga_webhook_block({ sdk: sdk })];
335
+ case 2:
336
+ _b.sent();
337
+ return [2 /*return*/];
338
+ }
339
+ });
340
+ });
341
+ };
342
+ if (require.main === module) {
343
+ console.log("Using API URL: ".concat(host));
344
+ var sdk_1 = new Session({ host: host });
345
+ var sdkNonAdmin_1 = new Session({ host: host });
346
+ var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
347
+ return __generator(this, function (_a) {
348
+ switch (_a.label) {
349
+ case 0: return [4 /*yield*/, setup_tests(sdk_1, sdkNonAdmin_1)];
350
+ case 1:
351
+ _a.sent();
352
+ return [4 /*yield*/, set_fields_order_templates_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
353
+ case 2:
354
+ _a.sent();
355
+ return [2 /*return*/];
356
+ }
357
+ });
358
+ }); };
359
+ runTests()
360
+ .then(function () {
361
+ console.log("set_fields_order_templates test suite completed successfully");
362
+ process.exit(0);
363
+ })
364
+ .catch(function (error) {
365
+ console.error("set_fields_order_templates test suite failed:", error);
366
+ process.exit(1);
367
+ });
368
+ }
369
+ //# sourceMappingURL=set_fields_order_templates.test.js.map