@tellescope/sdk 1.256.15 → 1.256.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/sdk.d.ts +2 -2
- package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.d.ts +5 -0
- package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.js +357 -0
- package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.js.map +1 -0
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +2 -0
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/esm/sdk.d.ts +2 -2
- package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.d.ts +5 -0
- package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.js +349 -0
- package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.js.map +1 -0
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +2 -0
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/tests/api_tests/security/file-link-session-confinement.test.ts +291 -0
- package/src/tests/tests.ts +2 -0
- package/test_generated.pdf +0 -0
package/lib/cjs/sdk.d.ts
CHANGED
|
@@ -4194,7 +4194,7 @@ export declare class Session extends SessionManager {
|
|
|
4194
4194
|
iat: number;
|
|
4195
4195
|
exp: number;
|
|
4196
4196
|
requiresMFA?: boolean | undefined;
|
|
4197
|
-
sessionScopes?: ("video-join-link" | "video-start-link" | "public-form" | "appointment-booking" | "ics-download" | "embeddables-token" | "portal-preview")[] | undefined;
|
|
4197
|
+
sessionScopes?: ("video-join-link" | "video-start-link" | "public-form" | "appointment-booking" | "ics-download" | "embeddables-token" | "portal-preview" | "file-download-link" | "file-download-shared-link")[] | undefined;
|
|
4198
4198
|
scopeContext?: import("@tellescope/types-models").SessionScopeContext | undefined;
|
|
4199
4199
|
allowedPaths?: string[] | undefined;
|
|
4200
4200
|
users?: number | undefined;
|
|
@@ -4359,7 +4359,7 @@ export declare class Session extends SessionManager {
|
|
|
4359
4359
|
iat: number;
|
|
4360
4360
|
exp: number;
|
|
4361
4361
|
requiresMFA?: boolean | undefined;
|
|
4362
|
-
sessionScopes?: ("video-join-link" | "video-start-link" | "public-form" | "appointment-booking" | "ics-download" | "embeddables-token" | "portal-preview")[] | undefined;
|
|
4362
|
+
sessionScopes?: ("video-join-link" | "video-start-link" | "public-form" | "appointment-booking" | "ics-download" | "embeddables-token" | "portal-preview" | "file-download-link" | "file-download-shared-link")[] | undefined;
|
|
4363
4363
|
scopeContext?: import("@tellescope/types-models").SessionScopeContext | undefined;
|
|
4364
4364
|
allowedPaths?: string[] | undefined;
|
|
4365
4365
|
users?: number | undefined;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Check } from "../../setup_isolated";
|
|
2
|
+
export declare const file_link_session_confinement_checks: () => Promise<Check[]>;
|
|
3
|
+
/** Asserting wrapper, for standalone runs and for sequential use in the suite. */
|
|
4
|
+
export declare const file_link_session_confinement_tests: () => Promise<void>;
|
|
5
|
+
//# sourceMappingURL=file-link-session-confinement.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-link-session-confinement.test.d.ts","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/file-link-session-confinement.test.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,EAEN,MAAM,sBAAsB,CAAA;AA2D7B,eAAO,MAAM,oCAAoC,QAAa,QAAQ,KAAK,EAAE,CA4M5E,CAAA;AAED,kFAAkF;AAClF,eAAO,MAAM,mCAAmC,qBAE/C,CAAA"}
|
|
@@ -0,0 +1,357 @@
|
|
|
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.file_link_session_confinement_tests = exports.file_link_session_confinement_checks = void 0;
|
|
43
|
+
require('source-map-support').install();
|
|
44
|
+
var axios_1 = __importDefault(require("axios"));
|
|
45
|
+
var setup_isolated_1 = require("../../setup_isolated");
|
|
46
|
+
var host = process.env.API_URL || 'http://localhost:8080';
|
|
47
|
+
var RAND = function () { return Math.random().toString(36).slice(2, 10); };
|
|
48
|
+
var probe = function (method, path, o) {
|
|
49
|
+
if (o === void 0) { o = {}; }
|
|
50
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
51
|
+
var r;
|
|
52
|
+
return __generator(this, function (_a) {
|
|
53
|
+
switch (_a.label) {
|
|
54
|
+
case 0: return [4 /*yield*/, axios_1.default.request({
|
|
55
|
+
method: method,
|
|
56
|
+
url: "".concat(host, "/v1").concat(path),
|
|
57
|
+
params: o.params,
|
|
58
|
+
data: o.data,
|
|
59
|
+
headers: o.token ? { Authorization: "Bearer ".concat(o.token) } : undefined,
|
|
60
|
+
validateStatus: function () { return true; },
|
|
61
|
+
})];
|
|
62
|
+
case 1:
|
|
63
|
+
r = _a.sent();
|
|
64
|
+
return [2 /*return*/, { status: r.status, body: r.data }];
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
var file_link_session_confinement_checks = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
70
|
+
var checks, record, tenant, sdk_1, enduser_1, newFile, fileA_1, fileB_1, mint, adminFiles, confinement_probes, plain, shared, methods, send, verify, _a, header, payload, decoded, forged, forgedSend, send, e_1;
|
|
71
|
+
return __generator(this, function (_b) {
|
|
72
|
+
switch (_b.label) {
|
|
73
|
+
case 0:
|
|
74
|
+
checks = [];
|
|
75
|
+
record = function (label, pass, detail) { return checks.push({ label: label, pass: pass, detail: detail }); };
|
|
76
|
+
_b.label = 1;
|
|
77
|
+
case 1:
|
|
78
|
+
_b.trys.push([1, , 22, 27]);
|
|
79
|
+
return [4 /*yield*/, (0, setup_isolated_1.setup_isolated_tenant)({
|
|
80
|
+
name: "FileLink ".concat(RAND()), users: [{ isAdmin: true }], apiKeys: 0,
|
|
81
|
+
})];
|
|
82
|
+
case 2:
|
|
83
|
+
tenant = _b.sent();
|
|
84
|
+
sdk_1 = tenant.sdk;
|
|
85
|
+
return [4 /*yield*/, sdk_1.api.endusers.createOne({
|
|
86
|
+
fname: 'FileLink', lname: 'Recipient',
|
|
87
|
+
email: "dontsend-filelink-".concat(RAND(), "@tellescope.com"),
|
|
88
|
+
phone: '+15555550100',
|
|
89
|
+
dateOfBirth: '01-01-1990',
|
|
90
|
+
})
|
|
91
|
+
// No S3 upload needed: prepare_file_upload inserts the files record with its secureName
|
|
92
|
+
// immediately, and file_download_URL only SIGNS a GET url — it never checks the object exists.
|
|
93
|
+
];
|
|
94
|
+
case 3:
|
|
95
|
+
enduser_1 = _b.sent();
|
|
96
|
+
newFile = function (name) { return __awaiter(void 0, void 0, void 0, function () {
|
|
97
|
+
return __generator(this, function (_a) {
|
|
98
|
+
switch (_a.label) {
|
|
99
|
+
case 0: return [4 /*yield*/, sdk_1.api.files.prepare_file_upload({
|
|
100
|
+
name: name,
|
|
101
|
+
type: 'application/pdf', size: 1000, enduserId: enduser_1.id,
|
|
102
|
+
})];
|
|
103
|
+
case 1: return [2 /*return*/, ((_a.sent()).file)];
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}); };
|
|
107
|
+
return [4 /*yield*/, newFile("shared-".concat(RAND(), ".pdf"))]; // the one that gets shared
|
|
108
|
+
case 4:
|
|
109
|
+
fileA_1 = _b.sent() // the one that gets shared
|
|
110
|
+
;
|
|
111
|
+
return [4 /*yield*/, newFile("private-".concat(RAND(), ".pdf"))
|
|
112
|
+
/**
|
|
113
|
+
* Mints a token exactly the way a real send does — get_templated_message is the endpoint the
|
|
114
|
+
* worker calls (worker/app.js handleOutgoingEmail).
|
|
115
|
+
*
|
|
116
|
+
* replaceLinks always rewrites the resolved link into a tracking redirect, so `plaintext` holds
|
|
117
|
+
* `doc (${API_URL}/r/<redirectToken>)` rather than the portal URL. Follow the 302 to recover it.
|
|
118
|
+
*/
|
|
119
|
+
]; // the rest of the patient's chart
|
|
120
|
+
case 5:
|
|
121
|
+
fileB_1 = _b.sent() // the rest of the patient's chart
|
|
122
|
+
;
|
|
123
|
+
mint = function (verb) { return __awaiter(void 0, void 0, void 0, function () {
|
|
124
|
+
var plaintext, redirectURL, r, location, token;
|
|
125
|
+
var _a, _b;
|
|
126
|
+
return __generator(this, function (_c) {
|
|
127
|
+
switch (_c.label) {
|
|
128
|
+
case 0: return [4 /*yield*/, sdk_1.api.templates.get_templated_message({
|
|
129
|
+
channel: 'Email',
|
|
130
|
+
userId: tenant.users[0].id,
|
|
131
|
+
enduserId: enduser_1.id,
|
|
132
|
+
message: "{{files.".concat(fileA_1.id, ".").concat(verb, ":doc}}"),
|
|
133
|
+
})];
|
|
134
|
+
case 1:
|
|
135
|
+
plaintext = (_c.sent()).plaintext;
|
|
136
|
+
redirectURL = (_a = plaintext.match(/\((https?:\/\/[^)\s]+)\)/)) === null || _a === void 0 ? void 0 : _a[1];
|
|
137
|
+
if (!redirectURL)
|
|
138
|
+
return [2 /*return*/, { token: undefined, detail: "no link resolved from: ".concat(plaintext) }];
|
|
139
|
+
return [4 /*yield*/, axios_1.default.get(redirectURL, { maxRedirects: 0, validateStatus: function () { return true; } })];
|
|
140
|
+
case 2:
|
|
141
|
+
r = _c.sent();
|
|
142
|
+
location = r.headers['location'];
|
|
143
|
+
if (!location)
|
|
144
|
+
return [2 /*return*/, { token: undefined, detail: "redirect did not 302 (".concat(r.status, ")") }];
|
|
145
|
+
token = (_b = new URL(location).searchParams.get('token')) !== null && _b !== void 0 ? _b : undefined;
|
|
146
|
+
return [2 /*return*/, { token: token, detail: token ? 'minted' : "no token in ".concat(location) }];
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}); };
|
|
150
|
+
return [4 /*yield*/, probe('get', '/files', { token: tenant.users[0].authToken })];
|
|
151
|
+
case 6:
|
|
152
|
+
adminFiles = _b.sent();
|
|
153
|
+
record('control: admin session lists files', adminFiles.status === 200, "status ".concat(adminFiles.status));
|
|
154
|
+
confinement_probes = function (variant, token) { return __awaiter(void 0, void 0, void 0, function () {
|
|
155
|
+
var p, _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, refreshed, leaked, refreshedToken, _s, _t, _u, _v;
|
|
156
|
+
var _w;
|
|
157
|
+
return __generator(this, function (_x) {
|
|
158
|
+
switch (_x.label) {
|
|
159
|
+
case 0:
|
|
160
|
+
p = function (label, expected, r) { return record("".concat(variant, " \u2014 ").concat(label), r.status === expected, "status ".concat(r.status, " (expected ").concat(expected, ")")); };
|
|
161
|
+
_a = p;
|
|
162
|
+
_b = ['1: downloads the shared file', 200];
|
|
163
|
+
return [4 /*yield*/, probe('get', '/file-download-URL', { token: token, params: { secureName: fileA_1.secureName } })];
|
|
164
|
+
case 1:
|
|
165
|
+
_a.apply(void 0, _b.concat([_x.sent()]));
|
|
166
|
+
_c = p;
|
|
167
|
+
_d = ['2: cannot download another file on the same patient', 403];
|
|
168
|
+
return [4 /*yield*/, probe('get', '/file-download-URL', { token: token, params: { secureName: fileB_1.secureName } })];
|
|
169
|
+
case 2:
|
|
170
|
+
_c.apply(void 0, _d.concat([_x.sent()]));
|
|
171
|
+
// validateInput merges query, then body, then params — body wins over query, so a pin checked
|
|
172
|
+
// against req.query rather than req.validated would be sidesteppable exactly like this.
|
|
173
|
+
_e = p;
|
|
174
|
+
_f = ['3: cannot smuggle another secureName through the body', 403];
|
|
175
|
+
return [4 /*yield*/, probe('get', '/file-download-URL', {
|
|
176
|
+
token: token,
|
|
177
|
+
params: { secureName: fileA_1.secureName }, data: { secureName: fileB_1.secureName },
|
|
178
|
+
})];
|
|
179
|
+
case 3:
|
|
180
|
+
// validateInput merges query, then body, then params — body wins over query, so a pin checked
|
|
181
|
+
// against req.query rather than req.validated would be sidesteppable exactly like this.
|
|
182
|
+
_e.apply(void 0, _f.concat([_x.sent()]));
|
|
183
|
+
// a listing would turn the pin into a directory of the patient's chart
|
|
184
|
+
_g = p;
|
|
185
|
+
_h = ['4: cannot list files', 403];
|
|
186
|
+
return [4 /*yield*/, probe('get', '/files', { token: token })];
|
|
187
|
+
case 4:
|
|
188
|
+
// a listing would turn the pin into a directory of the patient's chart
|
|
189
|
+
_g.apply(void 0, _h.concat([_x.sent()]));
|
|
190
|
+
_j = p;
|
|
191
|
+
_k = ['5a: cannot read chats', 403];
|
|
192
|
+
return [4 /*yield*/, probe('get', '/chats', { token: token })];
|
|
193
|
+
case 5:
|
|
194
|
+
_j.apply(void 0, _k.concat([_x.sent()]));
|
|
195
|
+
_l = p;
|
|
196
|
+
_m = ['5b: cannot read form responses', 403];
|
|
197
|
+
return [4 /*yield*/, probe('get', '/form-responses', { token: token })];
|
|
198
|
+
case 6:
|
|
199
|
+
_l.apply(void 0, _m.concat([_x.sent()]));
|
|
200
|
+
_o = p;
|
|
201
|
+
_p = ['5c: cannot read observations', 403];
|
|
202
|
+
return [4 /*yield*/, probe('get', '/enduser-observations', { token: token })];
|
|
203
|
+
case 7:
|
|
204
|
+
_o.apply(void 0, _p.concat([_x.sent()]));
|
|
205
|
+
_q = p;
|
|
206
|
+
_r = ['6: cannot update the patient', 403];
|
|
207
|
+
return [4 /*yield*/, probe('patch', "/enduser/".concat(enduser_1.id), { token: token, data: { updates: { fname: 'Overwritten' } } })];
|
|
208
|
+
case 8:
|
|
209
|
+
_q.apply(void 0, _r.concat([_x.sent()]));
|
|
210
|
+
return [4 /*yield*/, probe('post', '/refresh-enduser-session', { token: token })];
|
|
211
|
+
case 9:
|
|
212
|
+
refreshed = _x.sent();
|
|
213
|
+
p('7: can refresh its own session', 200, refreshed);
|
|
214
|
+
leaked = ['dateOfBirth', 'email', 'phone', 'fields', 'insurance', 'lname']
|
|
215
|
+
.filter(function (f) { var _a, _b; return ((_b = (_a = refreshed.body) === null || _a === void 0 ? void 0 : _a.enduser) !== null && _b !== void 0 ? _b : {})[f] !== undefined; });
|
|
216
|
+
record("".concat(variant, " \u2014 7b: refresh response withholds patient fields"), refreshed.status === 200 && leaked.length === 0, leaked.length ? "leaked: ".concat(leaked.join(', ')) : 'no patient fields in payload');
|
|
217
|
+
refreshedToken = (_w = refreshed.body) === null || _w === void 0 ? void 0 : _w.authToken;
|
|
218
|
+
if (!(typeof refreshedToken === 'string' && refreshedToken)) return [3 /*break*/, 12];
|
|
219
|
+
_s = p;
|
|
220
|
+
_t = ['8a: refreshed token still cannot download another file', 403];
|
|
221
|
+
return [4 /*yield*/, probe('get', '/file-download-URL', {
|
|
222
|
+
token: refreshedToken, params: { secureName: fileB_1.secureName },
|
|
223
|
+
})];
|
|
224
|
+
case 10:
|
|
225
|
+
_s.apply(void 0, _t.concat([_x.sent()]));
|
|
226
|
+
_u = p;
|
|
227
|
+
_v = ['8b: refreshed token still cannot update the patient', 403];
|
|
228
|
+
return [4 /*yield*/, probe('patch', "/enduser/".concat(enduser_1.id), {
|
|
229
|
+
token: refreshedToken, data: { updates: { fname: 'Overwritten' } },
|
|
230
|
+
})];
|
|
231
|
+
case 11:
|
|
232
|
+
_u.apply(void 0, _v.concat([_x.sent()]));
|
|
233
|
+
return [3 /*break*/, 13];
|
|
234
|
+
case 12:
|
|
235
|
+
record("".concat(variant, " \u2014 8: refreshed token available"), false, 'refresh returned no authToken');
|
|
236
|
+
_x.label = 13;
|
|
237
|
+
case 13: return [2 /*return*/];
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}); };
|
|
241
|
+
return [4 /*yield*/, mint('link')];
|
|
242
|
+
case 7:
|
|
243
|
+
plain = _b.sent();
|
|
244
|
+
if (!plain.token) return [3 /*break*/, 9];
|
|
245
|
+
return [4 /*yield*/, confinement_probes('link', plain.token)];
|
|
246
|
+
case 8:
|
|
247
|
+
_b.sent();
|
|
248
|
+
return [3 /*break*/, 10];
|
|
249
|
+
case 9:
|
|
250
|
+
record('link — minted', false, plain.detail);
|
|
251
|
+
_b.label = 10;
|
|
252
|
+
case 10: return [4 /*yield*/, mint('shared-link')];
|
|
253
|
+
case 11:
|
|
254
|
+
shared = _b.sent();
|
|
255
|
+
if (!shared.token) return [3 /*break*/, 13];
|
|
256
|
+
return [4 /*yield*/, confinement_probes('shared-link', shared.token)];
|
|
257
|
+
case 12:
|
|
258
|
+
_b.sent();
|
|
259
|
+
return [3 /*break*/, 14];
|
|
260
|
+
case 13:
|
|
261
|
+
// Before the shared-link verb exists the merge field does not resolve. Record it and skip the
|
|
262
|
+
// shared probes rather than throwing, so the first run reports the whole picture at once.
|
|
263
|
+
record('shared-link — minted', false, shared.detail);
|
|
264
|
+
_b.label = 14;
|
|
265
|
+
case 14:
|
|
266
|
+
if (!shared.token) return [3 /*break*/, 19];
|
|
267
|
+
return [4 /*yield*/, probe('get', '/endusers/otp-methods', { params: { token: shared.token } })];
|
|
268
|
+
case 15:
|
|
269
|
+
methods = _b.sent();
|
|
270
|
+
record('shared-link — 9: OTP methods are not offered', methods.status === 403, "status ".concat(methods.status, " (expected 403)"));
|
|
271
|
+
return [4 /*yield*/, probe('post', '/endusers/send-otp-code', {
|
|
272
|
+
data: { token: shared.token, method: 'email' },
|
|
273
|
+
})];
|
|
274
|
+
case 16:
|
|
275
|
+
send = _b.sent();
|
|
276
|
+
record('shared-link — 10: cannot make us send the patient a login code', send.status === 403, "status ".concat(send.status, " (expected 403)"));
|
|
277
|
+
return [4 /*yield*/, probe('post', '/endusers/verify-otp-code', {
|
|
278
|
+
data: { token: shared.token, code: '000000' },
|
|
279
|
+
})];
|
|
280
|
+
case 17:
|
|
281
|
+
verify = _b.sent();
|
|
282
|
+
record('shared-link — 11: OTP verification refuses the scope before checking the code', verify.status === 403, "status ".concat(verify.status, " (expected 403, 400 = reached the code check)"));
|
|
283
|
+
_a = shared.token.split('.'), header = _a[0], payload = _a[1];
|
|
284
|
+
decoded = JSON.parse(Buffer.from(payload, 'base64url').toString());
|
|
285
|
+
delete decoded.sessionScopes;
|
|
286
|
+
delete decoded.scopeContext;
|
|
287
|
+
forged = [
|
|
288
|
+
header,
|
|
289
|
+
Buffer.from(JSON.stringify(decoded)).toString('base64url'),
|
|
290
|
+
'not-a-real-signature',
|
|
291
|
+
].join('.');
|
|
292
|
+
return [4 /*yield*/, probe('post', '/endusers/send-otp-code', {
|
|
293
|
+
data: { token: forged, method: 'email' },
|
|
294
|
+
})];
|
|
295
|
+
case 18:
|
|
296
|
+
forgedSend = _b.sent();
|
|
297
|
+
record('shared-link — 12: a forged token cannot strip the scope to unlock OTP', forgedSend.status === 403 || forgedSend.status === 401 || forgedSend.status === 404, "status ".concat(forgedSend.status, " (expected 401/403/404; 204 = signature never verified)"));
|
|
298
|
+
_b.label = 19;
|
|
299
|
+
case 19:
|
|
300
|
+
if (!plain.token) return [3 /*break*/, 21];
|
|
301
|
+
return [4 /*yield*/, probe('post', '/endusers/send-otp-code', {
|
|
302
|
+
data: { token: plain.token, method: 'email' },
|
|
303
|
+
})];
|
|
304
|
+
case 20:
|
|
305
|
+
send = _b.sent();
|
|
306
|
+
record('link — 13: patient OTP recovery still works', send.status === 204, "status ".concat(send.status, " (expected 204)"));
|
|
307
|
+
_b.label = 21;
|
|
308
|
+
case 21: return [3 /*break*/, 27];
|
|
309
|
+
case 22:
|
|
310
|
+
if (!tenant) return [3 /*break*/, 26];
|
|
311
|
+
_b.label = 23;
|
|
312
|
+
case 23:
|
|
313
|
+
_b.trys.push([23, 25, , 26]);
|
|
314
|
+
return [4 /*yield*/, tenant.teardown()];
|
|
315
|
+
case 24:
|
|
316
|
+
_b.sent();
|
|
317
|
+
return [3 /*break*/, 26];
|
|
318
|
+
case 25:
|
|
319
|
+
e_1 = _b.sent();
|
|
320
|
+
console.error('teardown failed', e_1);
|
|
321
|
+
return [3 /*break*/, 26];
|
|
322
|
+
case 26: return [7 /*endfinally*/];
|
|
323
|
+
case 27: return [2 /*return*/, checks];
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
}); };
|
|
327
|
+
exports.file_link_session_confinement_checks = file_link_session_confinement_checks;
|
|
328
|
+
/** Asserting wrapper, for standalone runs and for sequential use in the suite. */
|
|
329
|
+
var file_link_session_confinement_tests = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
330
|
+
var _a, _b;
|
|
331
|
+
return __generator(this, function (_c) {
|
|
332
|
+
switch (_c.label) {
|
|
333
|
+
case 0:
|
|
334
|
+
_a = setup_isolated_1.assert_checks;
|
|
335
|
+
_b = ['Shared file link session confinement'];
|
|
336
|
+
return [4 /*yield*/, (0, exports.file_link_session_confinement_checks)()];
|
|
337
|
+
case 1:
|
|
338
|
+
_a.apply(void 0, _b.concat([_c.sent()]));
|
|
339
|
+
return [2 /*return*/];
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}); };
|
|
343
|
+
exports.file_link_session_confinement_tests = file_link_session_confinement_tests;
|
|
344
|
+
// Allow running this test file independently
|
|
345
|
+
if (require.main === module) {
|
|
346
|
+
console.log("\uD83C\uDF10 Using API URL: ".concat(host));
|
|
347
|
+
(0, exports.file_link_session_confinement_tests)()
|
|
348
|
+
.then(function () {
|
|
349
|
+
console.log("✅ file link session confinement test suite completed successfully");
|
|
350
|
+
process.exit(0);
|
|
351
|
+
})
|
|
352
|
+
.catch(function (error) {
|
|
353
|
+
console.error("❌ file link session confinement test suite failed:", error);
|
|
354
|
+
process.exit(1);
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
//# sourceMappingURL=file-link-session-confinement.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-link-session-confinement.test.js","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/file-link-session-confinement.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tests.d.ts","sourceRoot":"","sources":["../../../src/tests/tests.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tests.d.ts","sourceRoot":"","sources":["../../../src/tests/tests.ts"],"names":[],"mappings":"AA03EA,eAAO,MAAM,kCAAkC,qBAgJ9C,CAAA;AAED,eAAO,MAAM,mCAAmC,qBA2K/C,CAAA;AAGD,eAAO,MAAM,oBAAoB,qBAoHhC,CAAA;AAED,eAAO,MAAM,+BAA+B,qBAsF3C,CAAA;AAID,eAAO,MAAM,0BAA0B,qBAqCtC,CAAA;AAy1FD,eAAO,MAAM,cAAc,qBAqC1B,CAAA;AAotBD,eAAO,MAAM,0BAA0B,qBAmFtC,CAAA;AAqED,eAAO,MAAM,eAAe,qBAmD3B,CAAA;AAED,eAAO,MAAM,oBAAoB,6BAsBhC,CAAA;AAED,eAAO,MAAM,oCAAoC,qBAiqBhD,CAAA;AAED,eAAO,MAAM,mCAAmC,qBAkE/C,CAAA;AAqlDD,eAAO,MAAM,yBAAyB,qBA0DrC,CAAA;AAED,eAAO,MAAM,kBAAkB,qBAmK9B,CAAA;AAED,eAAO,MAAM,sBAAsB,qBA0BlC,CAAA;AAGD,eAAO,MAAM,mBAAmB,qBAmC/B,CAAA;AAED,eAAO,MAAM,gCAAgC,mCA8C5C,CAAA;AAED,eAAO,MAAM,cAAc,qBA+b1B,CAAA;AAGD,eAAO,MAAM,oBAAoB,uBAuBhC,CAAA;AA4wBD,eAAO,MAAM,4BAA4B,qBAiFxC,CAAA;AAED,eAAO,MAAM,+BAA+B,qBA4U3C,CAAA;AAED,eAAO,MAAM,gDAAgD,qBAyD5D,CAAA;AAED,eAAO,MAAM,qBAAqB,qBAwIjC,CAAA"}
|
package/lib/cjs/tests/tests.js
CHANGED
|
@@ -210,6 +210,7 @@ var organization_signup_test_1 = require("./api_tests/organization_signup.test")
|
|
|
210
210
|
var add_to_journey_foreign_enduserid_test_1 = require("./api_tests/security/add-to-journey-foreign-enduserid.test");
|
|
211
211
|
var tickets_bulk_assign_from_queue_test_1 = require("./api_tests/tickets_bulk_assign_from_queue.test");
|
|
212
212
|
var enduser_observations_auto_review_test_1 = require("./api_tests/enduser_observations_auto_review.test");
|
|
213
|
+
var file_link_session_confinement_test_1 = require("./api_tests/security/file-link-session-confinement.test");
|
|
213
214
|
var setup_isolated_1 = require("./setup_isolated");
|
|
214
215
|
var elation_user_id_test_1 = require("./api_tests/elation_user_id.test");
|
|
215
216
|
var organization_settings_duplicates_test_1 = require("./api_tests/organization_settings_duplicates.test");
|
|
@@ -17496,6 +17497,7 @@ var ip_address_form_tests = function () { return __awaiter(void 0, void 0, void
|
|
|
17496
17497
|
{ name: 'Tickets bulk assign from queue', run: tickets_bulk_assign_from_queue_test_1.tickets_bulk_assign_from_queue_checks },
|
|
17497
17498
|
{ name: 'Vital auto-review on create', run: enduser_observations_auto_review_test_1.enduser_observations_auto_review_checks },
|
|
17498
17499
|
{ name: '$JS in stored conditional logic', run: form_logic_js_execution_test_1.form_logic_js_execution_checks },
|
|
17500
|
+
{ name: 'Shared file link session confinement', run: file_link_session_confinement_test_1.file_link_session_confinement_checks },
|
|
17499
17501
|
])];
|
|
17500
17502
|
case 23:
|
|
17501
17503
|
// Isolated, tenant-provisioned suites run first and CONCURRENTLY: each provisions its own
|