@tellescope/sdk 1.256.1 → 1.256.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/sdk.d.ts +2 -2
- package/lib/cjs/tests/api_tests/appointment_link_expiration.test.d.ts +6 -0
- package/lib/cjs/tests/api_tests/appointment_link_expiration.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/appointment_link_expiration.test.js +163 -0
- package/lib/cjs/tests/api_tests/appointment_link_expiration.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/embeddables_auth_token.test.d.ts +6 -0
- package/lib/cjs/tests/api_tests/embeddables_auth_token.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/embeddables_auth_token.test.js +354 -0
- package/lib/cjs/tests/api_tests/embeddables_auth_token.test.js.map +1 -0
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +205 -193
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/cjs/tests/unit_tests/phone_validation.test.d.ts +3 -0
- package/lib/cjs/tests/unit_tests/phone_validation.test.d.ts.map +1 -0
- package/lib/cjs/tests/unit_tests/phone_validation.test.js +96 -0
- package/lib/cjs/tests/unit_tests/phone_validation.test.js.map +1 -0
- package/lib/esm/enduser.d.ts +0 -1
- package/lib/esm/enduser.d.ts.map +1 -1
- package/lib/esm/sdk.d.ts +4 -5
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/session.d.ts +0 -1
- package/lib/esm/session.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/appointment_link_expiration.test.d.ts +6 -0
- package/lib/esm/tests/api_tests/appointment_link_expiration.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/appointment_link_expiration.test.js +156 -0
- package/lib/esm/tests/api_tests/appointment_link_expiration.test.js.map +1 -0
- package/lib/esm/tests/api_tests/embeddables_auth_token.test.d.ts +6 -0
- package/lib/esm/tests/api_tests/embeddables_auth_token.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/embeddables_auth_token.test.js +347 -0
- package/lib/esm/tests/api_tests/embeddables_auth_token.test.js.map +1 -0
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +205 -193
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/esm/tests/unit_tests/phone_validation.test.d.ts +3 -0
- package/lib/esm/tests/unit_tests/phone_validation.test.d.ts.map +1 -0
- package/lib/esm/tests/unit_tests/phone_validation.test.js +93 -0
- package/lib/esm/tests/unit_tests/phone_validation.test.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/tests/api_tests/appointment_link_expiration.test.ts +92 -0
- package/src/tests/api_tests/embeddables_auth_token.test.ts +417 -0
- package/src/tests/tests.ts +6 -0
- package/src/tests/unit_tests/phone_validation.test.ts +108 -0
- package/test_generated.pdf +0 -0
package/lib/cjs/sdk.d.ts
CHANGED
|
@@ -4193,7 +4193,7 @@ export declare class Session extends SessionManager {
|
|
|
4193
4193
|
iat: number;
|
|
4194
4194
|
exp: number;
|
|
4195
4195
|
requiresMFA?: boolean | undefined;
|
|
4196
|
-
sessionScopes?: ("video-join-link" | "video-start-link" | "public-form" | "appointment-booking" | "ics-download")[] | undefined;
|
|
4196
|
+
sessionScopes?: ("video-join-link" | "video-start-link" | "public-form" | "appointment-booking" | "ics-download" | "embeddables-token")[] | undefined;
|
|
4197
4197
|
scopeContext?: import("@tellescope/types-models").SessionScopeContext | undefined;
|
|
4198
4198
|
allowedPaths?: string[] | undefined;
|
|
4199
4199
|
users?: number | undefined;
|
|
@@ -4358,7 +4358,7 @@ export declare class Session extends SessionManager {
|
|
|
4358
4358
|
iat: number;
|
|
4359
4359
|
exp: number;
|
|
4360
4360
|
requiresMFA?: boolean | undefined;
|
|
4361
|
-
sessionScopes?: ("video-join-link" | "video-start-link" | "public-form" | "appointment-booking" | "ics-download")[] | undefined;
|
|
4361
|
+
sessionScopes?: ("video-join-link" | "video-start-link" | "public-form" | "appointment-booking" | "ics-download" | "embeddables-token")[] | undefined;
|
|
4362
4362
|
scopeContext?: import("@tellescope/types-models").SessionScopeContext | undefined;
|
|
4363
4363
|
allowedPaths?: string[] | undefined;
|
|
4364
4364
|
users?: number | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appointment_link_expiration.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/api_tests/appointment_link_expiration.test.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAmCnC,eAAO,MAAM,iCAAiC;SAA2B,OAAO;iBAAe,OAAO;mBA+BrG,CAAA"}
|
|
@@ -0,0 +1,163 @@
|
|
|
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.appointment_link_expiration_tests = void 0;
|
|
43
|
+
require('source-map-support').install();
|
|
44
|
+
var axios_1 = __importDefault(require("axios"));
|
|
45
|
+
var sdk_1 = require("../../sdk");
|
|
46
|
+
var testing_1 = require("@tellescope/testing");
|
|
47
|
+
var setup_1 = require("../setup");
|
|
48
|
+
var host = process.env.API_URL || 'http://localhost:8080';
|
|
49
|
+
var ONE_DAY_IN_SECONDS = 86400;
|
|
50
|
+
var EVENT_DAYS_OUT = 120; // under the old expiry (event lead time + 4 weeks) this token lived ~148 days
|
|
51
|
+
// Decode a JWT payload WITHOUT verifying it — the signing key is server-side only, and the only
|
|
52
|
+
// thing under test is the lifetime the server stamped on the token.
|
|
53
|
+
var decode_jwt_payload = function (token) {
|
|
54
|
+
var _a = token.split('.'), payload = _a[1];
|
|
55
|
+
if (!payload)
|
|
56
|
+
throw new Error("Not a JWT");
|
|
57
|
+
return JSON.parse(Buffer.from(payload.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString('utf8'));
|
|
58
|
+
};
|
|
59
|
+
// The API returns a /r/<token> shortlink, not the destination — follow one hop and pull the
|
|
60
|
+
// `token` query param out of the URL the patient actually lands on.
|
|
61
|
+
var resolve_redirect_token = function (link) { return __awaiter(void 0, void 0, void 0, function () {
|
|
62
|
+
var _a, status, headers, location, token;
|
|
63
|
+
return __generator(this, function (_b) {
|
|
64
|
+
switch (_b.label) {
|
|
65
|
+
case 0: return [4 /*yield*/, axios_1.default.get(link, {
|
|
66
|
+
maxRedirects: 0,
|
|
67
|
+
validateStatus: function () { return true; },
|
|
68
|
+
})];
|
|
69
|
+
case 1:
|
|
70
|
+
_a = _b.sent(), status = _a.status, headers = _a.headers;
|
|
71
|
+
location = headers['location'];
|
|
72
|
+
if (!location)
|
|
73
|
+
throw new Error("Expected a redirect from ".concat(link, ", got status ").concat(status));
|
|
74
|
+
token = new URL(location).searchParams.get('token');
|
|
75
|
+
if (!token)
|
|
76
|
+
throw new Error("No token query param in redirect destination: ".concat(location));
|
|
77
|
+
return [2 /*return*/, token];
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}); };
|
|
81
|
+
var appointment_link_expiration_tests = function (_a) {
|
|
82
|
+
var sdk = _a.sdk;
|
|
83
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
84
|
+
var enduser, event, link, _b, iat, exp, _c, lifetimeInSeconds_1;
|
|
85
|
+
return __generator(this, function (_d) {
|
|
86
|
+
switch (_d.label) {
|
|
87
|
+
case 0:
|
|
88
|
+
(0, testing_1.log_header)("Appointment Link Expiration");
|
|
89
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
90
|
+
email: "appointment-link-expiration-".concat(Date.now(), "@tellescope.com"),
|
|
91
|
+
})];
|
|
92
|
+
case 1:
|
|
93
|
+
enduser = _d.sent();
|
|
94
|
+
return [4 /*yield*/, sdk.api.calendar_events.createOne({
|
|
95
|
+
title: 'Appointment Link Expiration Test',
|
|
96
|
+
durationInMinutes: 30,
|
|
97
|
+
startTimeInMS: Date.now() + EVENT_DAYS_OUT * ONE_DAY_IN_SECONDS * 1000,
|
|
98
|
+
enableVideoCall: true,
|
|
99
|
+
attendees: [{ type: 'enduser', id: enduser.id }],
|
|
100
|
+
})];
|
|
101
|
+
case 2:
|
|
102
|
+
event = _d.sent();
|
|
103
|
+
_d.label = 3;
|
|
104
|
+
case 3:
|
|
105
|
+
_d.trys.push([3, , 7, 10]);
|
|
106
|
+
return [4 /*yield*/, sdk.api.calendar_events.generate_meeting_link({
|
|
107
|
+
eventId: event.id,
|
|
108
|
+
enduserId: enduser.id,
|
|
109
|
+
})];
|
|
110
|
+
case 4:
|
|
111
|
+
link = (_d.sent()).link;
|
|
112
|
+
_c = decode_jwt_payload;
|
|
113
|
+
return [4 /*yield*/, resolve_redirect_token(link)];
|
|
114
|
+
case 5:
|
|
115
|
+
_b = _c.apply(void 0, [_d.sent()]), iat = _b.iat, exp = _b.exp;
|
|
116
|
+
lifetimeInSeconds_1 = exp - iat;
|
|
117
|
+
return [4 /*yield*/, (0, testing_1.async_test)("meeting link token for an event ".concat(EVENT_DAYS_OUT, " days out expires within 24h"), function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
118
|
+
return [2 /*return*/, lifetimeInSeconds_1];
|
|
119
|
+
}); }); }, { onResult: function (lifetime) { return lifetime > 0 && lifetime <= ONE_DAY_IN_SECONDS; } })];
|
|
120
|
+
case 6:
|
|
121
|
+
_d.sent();
|
|
122
|
+
return [3 /*break*/, 10];
|
|
123
|
+
case 7: return [4 /*yield*/, sdk.api.calendar_events.deleteOne(event.id).catch(console.error)];
|
|
124
|
+
case 8:
|
|
125
|
+
_d.sent();
|
|
126
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(enduser.id).catch(console.error)];
|
|
127
|
+
case 9:
|
|
128
|
+
_d.sent();
|
|
129
|
+
return [7 /*endfinally*/];
|
|
130
|
+
case 10: return [2 /*return*/];
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
exports.appointment_link_expiration_tests = appointment_link_expiration_tests;
|
|
136
|
+
// Allow running this test file independently
|
|
137
|
+
if (require.main === module) {
|
|
138
|
+
var sdk_2 = new sdk_1.Session({ host: host });
|
|
139
|
+
var sdkNonAdmin_1 = new sdk_1.Session({ host: host });
|
|
140
|
+
var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
141
|
+
return __generator(this, function (_a) {
|
|
142
|
+
switch (_a.label) {
|
|
143
|
+
case 0: return [4 /*yield*/, (0, setup_1.setup_tests)(sdk_2, sdkNonAdmin_1)];
|
|
144
|
+
case 1:
|
|
145
|
+
_a.sent();
|
|
146
|
+
return [4 /*yield*/, (0, exports.appointment_link_expiration_tests)({ sdk: sdk_2, sdkNonAdmin: sdkNonAdmin_1 })];
|
|
147
|
+
case 2:
|
|
148
|
+
_a.sent();
|
|
149
|
+
return [2 /*return*/];
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}); };
|
|
153
|
+
runTests()
|
|
154
|
+
.then(function () {
|
|
155
|
+
console.log("✅ Appointment link expiration test suite completed successfully");
|
|
156
|
+
process.exit(0);
|
|
157
|
+
})
|
|
158
|
+
.catch(function (error) {
|
|
159
|
+
console.error("❌ Appointment link expiration test suite failed:", error);
|
|
160
|
+
process.exit(1);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=appointment_link_expiration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appointment_link_expiration.test.js","sourceRoot":"","sources":["../../../../src/tests/api_tests/appointment_link_expiration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embeddables_auth_token.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/api_tests/embeddables_auth_token.test.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAkB,MAAM,WAAW,CAAA;AA+CnD,eAAO,MAAM,4BAA4B;SAAwC,OAAO;iBAAe,OAAO;mBAwV7G,CAAA"}
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
+
function step(op) {
|
|
27
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
+
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;
|
|
30
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
+
switch (op[0]) {
|
|
32
|
+
case 0: case 1: t = op; break;
|
|
33
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
+
default:
|
|
37
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
+
if (t[2]) _.ops.pop();
|
|
42
|
+
_.trys.pop(); continue;
|
|
43
|
+
}
|
|
44
|
+
op = body.call(thisArg, _);
|
|
45
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
50
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
51
|
+
};
|
|
52
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
+
exports.embeddables_auth_token_tests = void 0;
|
|
54
|
+
require('source-map-support').install();
|
|
55
|
+
var axios_1 = __importDefault(require("axios"));
|
|
56
|
+
var sdk_1 = require("../../sdk");
|
|
57
|
+
var testing_1 = require("@tellescope/testing");
|
|
58
|
+
var setup_1 = require("../setup");
|
|
59
|
+
var host = process.env.API_URL || 'http://localhost:8080';
|
|
60
|
+
/**
|
|
61
|
+
* {{enduser.embeddablesAuthToken}} — a 24h, path-confined enduser token that can be spliced into a
|
|
62
|
+
* third-party URL by a message author.
|
|
63
|
+
*
|
|
64
|
+
* The Embeddables handoff: Tellescope messages a patient a link to an Embeddables-hosted page with an
|
|
65
|
+
* enduser token in the URL; that page reads the patient's own record with it, refreshes it on load, and
|
|
66
|
+
* falls back to the existing OTP flow once it has expired.
|
|
67
|
+
*
|
|
68
|
+
* Everything here renders through POST /v1/templated-message, which runs the real
|
|
69
|
+
* process_message -> getTemplatedData path — the same code a real send uses, including the
|
|
70
|
+
* login_enduser minting branch. No messages are sent.
|
|
71
|
+
*
|
|
72
|
+
* Two facts the assertions rest on:
|
|
73
|
+
* - a BARE url/token is not shortened (only the {url}[text] syntax becomes a /r/<token> redirect), so
|
|
74
|
+
* the raw JWT lands in `plaintext` and is directly readable — unlike {{portal.link...}}, whose token
|
|
75
|
+
* the shortener swallows.
|
|
76
|
+
* - decoding needs no dependency: the test asserts on CLAIMS, never on signature validity.
|
|
77
|
+
*/
|
|
78
|
+
var decodeJwt = function (jwt) {
|
|
79
|
+
var _a = jwt.split('.'), payload = _a[1];
|
|
80
|
+
if (!payload)
|
|
81
|
+
throw new Error("not a JWT: ".concat(jwt));
|
|
82
|
+
return JSON.parse(Buffer.from(payload, 'base64url').toString());
|
|
83
|
+
};
|
|
84
|
+
var looksLikeJwt = function (s) { return s.split('.').length === 3 && s.split('.').every(function (p) { return !!p; }); };
|
|
85
|
+
var SECONDS_IN_DAY = 86400;
|
|
86
|
+
var embeddables_auth_token_tests = function (_a) {
|
|
87
|
+
var sdk = _a.sdk, sdkNonAdmin = _a.sdkNonAdmin;
|
|
88
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
89
|
+
var businessId, request, enduser, otherEnduser, collisionEnduser, render_1, renderToken, defaultToken, shortToken, cappedToken, _i, _b, ttl, fallback, inURL, urlPrefix, collisionRendered, mixed, _c, renderedFname, mixedToken, scopedAuthToken, scopedSession, ownRead, ownReadViaSDK, bulkRead, refreshed, refreshedClaims, denied, _d, denied_1, _e, label, method, path, data, expected, r, afterWriteAttempts, crossRead_1, leaked, tokenA, sessionA, preBurn, portalToken, tokenB, postBurnA, postBurnB, postBurnPortal, otpMethods, nonAdminToken;
|
|
90
|
+
var _f;
|
|
91
|
+
return __generator(this, function (_g) {
|
|
92
|
+
switch (_g.label) {
|
|
93
|
+
case 0:
|
|
94
|
+
(0, testing_1.log_header)("Embeddables Auth Token Merge Field Tests");
|
|
95
|
+
businessId = sdk.userInfo.businessId;
|
|
96
|
+
request = function (token, method, path, data) { return __awaiter(void 0, void 0, void 0, function () {
|
|
97
|
+
var r;
|
|
98
|
+
return __generator(this, function (_a) {
|
|
99
|
+
switch (_a.label) {
|
|
100
|
+
case 0: return [4 /*yield*/, axios_1.default.request(__assign(__assign({ method: method, url: "".concat(host, "/v1").concat(path) }, method === 'get' ? { params: data } : { data: data }), { headers: { Authorization: "Bearer ".concat(token) }, validateStatus: function () { return true; } }))];
|
|
101
|
+
case 1:
|
|
102
|
+
r = _a.sent();
|
|
103
|
+
return [2 /*return*/, { status: r.status, body: r.data }];
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}); };
|
|
107
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
108
|
+
fname: 'Embeddables',
|
|
109
|
+
lname: 'Patient',
|
|
110
|
+
email: "embeddables-token-".concat(Date.now(), "@tellescope.com"),
|
|
111
|
+
phone: '+15555555555',
|
|
112
|
+
})];
|
|
113
|
+
case 1:
|
|
114
|
+
enduser = _g.sent();
|
|
115
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
116
|
+
fname: 'Other',
|
|
117
|
+
lname: 'Patient',
|
|
118
|
+
email: "embeddables-other-".concat(Date.now(), "@tellescope.com"),
|
|
119
|
+
dateOfBirth: '01-01-1990',
|
|
120
|
+
})
|
|
121
|
+
// a tenant custom field with the same name as the merge field, to prove it cannot shadow it
|
|
122
|
+
];
|
|
123
|
+
case 2:
|
|
124
|
+
otherEnduser = _g.sent();
|
|
125
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
126
|
+
fname: 'Collision',
|
|
127
|
+
fields: { embeddablesAuthToken: 'SHOULD_NOT_APPEAR' },
|
|
128
|
+
})];
|
|
129
|
+
case 3:
|
|
130
|
+
collisionEnduser = _g.sent();
|
|
131
|
+
_g.label = 4;
|
|
132
|
+
case 4:
|
|
133
|
+
_g.trys.push([4, , 35, 37]);
|
|
134
|
+
render_1 = function (message, o) { return __awaiter(void 0, void 0, void 0, function () {
|
|
135
|
+
var caller, r;
|
|
136
|
+
var _a, _b;
|
|
137
|
+
return __generator(this, function (_c) {
|
|
138
|
+
switch (_c.label) {
|
|
139
|
+
case 0:
|
|
140
|
+
caller = (_a = o === null || o === void 0 ? void 0 : o.caller) !== null && _a !== void 0 ? _a : sdk;
|
|
141
|
+
return [4 /*yield*/, caller.api.templates.get_templated_message({
|
|
142
|
+
message: message,
|
|
143
|
+
enduserId: (_b = o === null || o === void 0 ? void 0 : o.enduserId) !== null && _b !== void 0 ? _b : enduser.id,
|
|
144
|
+
userId: caller.userInfo.id,
|
|
145
|
+
channel: 'Chat',
|
|
146
|
+
})];
|
|
147
|
+
case 1:
|
|
148
|
+
r = _c.sent();
|
|
149
|
+
return [2 /*return*/, r.plaintext];
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}); };
|
|
153
|
+
renderToken = function (message, o) { return __awaiter(void 0, void 0, void 0, function () {
|
|
154
|
+
var _a;
|
|
155
|
+
return __generator(this, function (_b) {
|
|
156
|
+
switch (_b.label) {
|
|
157
|
+
case 0:
|
|
158
|
+
_a = decodeJwt;
|
|
159
|
+
return [4 /*yield*/, render_1(message, o)];
|
|
160
|
+
case 1: return [2 /*return*/, (_a.apply(void 0, [_b.sent()]))];
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}); };
|
|
164
|
+
return [4 /*yield*/, renderToken('{{enduser.embeddablesAuthToken}}')];
|
|
165
|
+
case 5:
|
|
166
|
+
defaultToken = _g.sent();
|
|
167
|
+
(0, testing_1.assert)(defaultToken.type === 'enduser', "token type is '".concat(defaultToken.type, "', expected 'enduser'"), 'merge field mints an enduser token');
|
|
168
|
+
(0, testing_1.assert)(defaultToken.id === enduser.id, "token id is '".concat(defaultToken.id, "', expected '").concat(enduser.id, "'"), 'token is bound to the templated enduser');
|
|
169
|
+
(0, testing_1.assert)(defaultToken.businessId === businessId, "token businessId is '".concat(defaultToken.businessId, "', expected '").concat(businessId, "'"), 'token carries the correct businessId');
|
|
170
|
+
(0, testing_1.assert)(JSON.stringify(defaultToken.sessionScopes) === JSON.stringify(['embeddables-token']), "sessionScopes is ".concat(JSON.stringify(defaultToken.sessionScopes), ", expected [\"embeddables-token\"]"), 'token is confined to exactly the embeddables-token scope');
|
|
171
|
+
(0, testing_1.assert)(defaultToken.exp - defaultToken.iat === SECONDS_IN_DAY, "default TTL is ".concat(defaultToken.exp - defaultToken.iat, "s, expected ").concat(SECONDS_IN_DAY, "s"), 'default TTL is 24h, matching {{portal.link...}}');
|
|
172
|
+
return [4 /*yield*/, renderToken('{{enduser.embeddablesAuthToken:3600}}')];
|
|
173
|
+
case 6:
|
|
174
|
+
shortToken = _g.sent();
|
|
175
|
+
(0, testing_1.assert)(shortToken.exp - shortToken.iat === 3600, "configured TTL is ".concat(shortToken.exp - shortToken.iat, "s, expected 3600s"), 'a caller-specified TTL is honored');
|
|
176
|
+
return [4 /*yield*/, renderToken('{{enduser.embeddablesAuthToken:999999}}')];
|
|
177
|
+
case 7:
|
|
178
|
+
cappedToken = _g.sent();
|
|
179
|
+
(0, testing_1.assert)(cappedToken.exp - cappedToken.iat === SECONDS_IN_DAY, "capped TTL is ".concat(cappedToken.exp - cappedToken.iat, "s, expected ").concat(SECONDS_IN_DAY, "s"), 'the 24h cap holds — the minted TTL is configurable downward only');
|
|
180
|
+
_i = 0, _b = ['abc', '-5', '0'];
|
|
181
|
+
_g.label = 8;
|
|
182
|
+
case 8:
|
|
183
|
+
if (!(_i < _b.length)) return [3 /*break*/, 11];
|
|
184
|
+
ttl = _b[_i];
|
|
185
|
+
return [4 /*yield*/, renderToken("{{enduser.embeddablesAuthToken:".concat(ttl, "}}"))];
|
|
186
|
+
case 9:
|
|
187
|
+
fallback = _g.sent();
|
|
188
|
+
(0, testing_1.assert)(fallback.exp - fallback.iat === SECONDS_IN_DAY, "TTL ':".concat(ttl, "' produced ").concat(fallback.exp - fallback.iat, "s, expected a ").concat(SECONDS_IN_DAY, "s fallback"), "an unparseable TTL (':".concat(ttl, "') falls back to 24h"));
|
|
189
|
+
_g.label = 10;
|
|
190
|
+
case 10:
|
|
191
|
+
_i++;
|
|
192
|
+
return [3 /*break*/, 8];
|
|
193
|
+
case 11: return [4 /*yield*/, render_1('https://example.com/?token={{enduser.embeddablesAuthToken}}')];
|
|
194
|
+
case 12:
|
|
195
|
+
inURL = _g.sent();
|
|
196
|
+
urlPrefix = 'https://example.com/?token=';
|
|
197
|
+
(0, testing_1.assert)(inURL.startsWith(urlPrefix), "rendered URL was '".concat(inURL, "'"), 'the token substitutes inline into an arbitrary URL');
|
|
198
|
+
(0, testing_1.assert)(!inURL.includes('/r/'), "rendered URL was shortened: '".concat(inURL, "'"), 'a bare URL is not run through the link shortener');
|
|
199
|
+
(0, testing_1.assert)(decodeJwt(inURL.slice(urlPrefix.length)).id === enduser.id, 'the JWT spliced into the URL did not decode to this enduser', 'the JWT survives intact inside the URL');
|
|
200
|
+
return [4 /*yield*/, render_1('{{enduser.embeddablesAuthToken}}', { enduserId: collisionEnduser.id })];
|
|
201
|
+
case 13:
|
|
202
|
+
collisionRendered = _g.sent();
|
|
203
|
+
(0, testing_1.assert)(!collisionRendered.includes('SHOULD_NOT_APPEAR') && looksLikeJwt(collisionRendered), "custom field shadowed the merge field: '".concat(collisionRendered, "'"), 'a tenant custom field named embeddablesAuthToken cannot shadow the merge field');
|
|
204
|
+
(0, testing_1.assert)(decodeJwt(collisionRendered).id === collisionEnduser.id, 'the collision-guard render did not decode to a JWT for that enduser', 'the collision-guard render is a real token');
|
|
205
|
+
return [4 /*yield*/, render_1('{{enduser.fname}}|{{enduser.embeddablesAuthToken}}')];
|
|
206
|
+
case 14:
|
|
207
|
+
mixed = _g.sent();
|
|
208
|
+
_c = mixed.split('|'), renderedFname = _c[0], mixedToken = _c[1];
|
|
209
|
+
(0, testing_1.assert)(renderedFname === 'Embeddables', "expected fname 'Embeddables', got '".concat(renderedFname, "'"), 'ordinary enduser merge fields still resolve alongside the new one');
|
|
210
|
+
(0, testing_1.assert)(looksLikeJwt(mixedToken !== null && mixedToken !== void 0 ? mixedToken : ''), "expected a JWT after the fname, got '".concat(mixedToken, "'"), 'the token still renders when combined with other fields');
|
|
211
|
+
return [4 /*yield*/, render_1('{{enduser.embeddablesAuthToken}}')];
|
|
212
|
+
case 15:
|
|
213
|
+
scopedAuthToken = _g.sent();
|
|
214
|
+
scopedSession = new sdk_1.EnduserSession({ host: host, businessId: businessId, authToken: scopedAuthToken });
|
|
215
|
+
return [4 /*yield*/, request(scopedAuthToken, 'get', "/enduser/".concat(enduser.id))];
|
|
216
|
+
case 16:
|
|
217
|
+
ownRead = _g.sent();
|
|
218
|
+
(0, testing_1.assert)(ownRead.status === 200 && ((_f = ownRead.body) === null || _f === void 0 ? void 0 : _f.id) === enduser.id, "own-record read returned ".concat(ownRead.status, ": ").concat(JSON.stringify(ownRead.body)), 'the token reads its own enduser record (GET /enduser/:id)');
|
|
219
|
+
return [4 /*yield*/, scopedSession.api.endusers.getOne(enduser.id)];
|
|
220
|
+
case 17:
|
|
221
|
+
ownReadViaSDK = _g.sent();
|
|
222
|
+
(0, testing_1.assert)((ownReadViaSDK === null || ownReadViaSDK === void 0 ? void 0 : ownReadViaSDK.id) === enduser.id, "SDK getOne returned ".concat(JSON.stringify(ownReadViaSDK)), 'the SDK singular-read path works with the token');
|
|
223
|
+
return [4 /*yield*/, request(scopedAuthToken, 'post', '/endusers/bulk-read', { ids: [enduser.id] })];
|
|
224
|
+
case 18:
|
|
225
|
+
bulkRead = _g.sent();
|
|
226
|
+
(0, testing_1.assert)(bulkRead.status === 403, "bulk-read returned ".concat(bulkRead.status, ", expected 403"), 'findById({ batch: true }) is NOT granted — bulk-read is a separate route');
|
|
227
|
+
return [4 /*yield*/, scopedSession.refresh_session()];
|
|
228
|
+
case 19:
|
|
229
|
+
refreshed = _g.sent();
|
|
230
|
+
refreshedClaims = decodeJwt(refreshed.authToken);
|
|
231
|
+
(0, testing_1.assert)(JSON.stringify(refreshedClaims.sessionScopes) === JSON.stringify(['embeddables-token']), "refreshed token sessionScopes is ".concat(JSON.stringify(refreshedClaims.sessionScopes)), 'refresh_session preserves the confinement — no escalation via refresh');
|
|
232
|
+
(0, testing_1.assert)(refreshedClaims.id === enduser.id, "refreshed token id is '".concat(refreshedClaims.id, "'"), 'refresh_session returns a token for the same enduser');
|
|
233
|
+
denied = [
|
|
234
|
+
// deliberately ungranted: it returns only the decoded token the caller already holds. Asserting
|
|
235
|
+
// the 403 means a future widening has to be a conscious edit.
|
|
236
|
+
['current_session_info', 'get', '/enduser-session-info', undefined, 403],
|
|
237
|
+
// no write grant at all — and email/phone are login channels (password reset resolves by email,
|
|
238
|
+
// OTP delivers to phone), so specifically confirm they cannot be repointed
|
|
239
|
+
['updateOne (fname)', 'patch', "/enduser/".concat(enduser.id), { updates: { fname: 'Hacked' } }, 403],
|
|
240
|
+
['updateOne (email)', 'patch', "/enduser/".concat(enduser.id), { updates: { email: 'attacker@example.com' } }, 403],
|
|
241
|
+
['updateOne (phone)', 'patch', "/enduser/".concat(enduser.id), { updates: { phone: '+15550001111' } }, 403],
|
|
242
|
+
['chat_rooms.getSome', 'get', '/chat-rooms', undefined, 403],
|
|
243
|
+
['load_inbox_data', 'get', '/endusers/load-inbox-data', { limit: 10 }, 401],
|
|
244
|
+
['endusers.getSome (readMany)', 'get', '/endusers', undefined, 403],
|
|
245
|
+
// THE FILTER ORACLE. The bare singular-read route is the same handler as /enduser/:id, but with no
|
|
246
|
+
// path id it evaluates a caller-supplied filter against UNREDACTED records and answers 200 on match
|
|
247
|
+
// / 400 on miss — a per-field probe over every enduser in the business (applyRedactions strips the
|
|
248
|
+
// response body, never the filter). Both syntaxes are asserted because dropping mdbFilter alone
|
|
249
|
+
// would not close it: `filter`'s _gt/_lt/_in operators binary-search a value just as well. A 403
|
|
250
|
+
// here means the route is unreachable, not that one filter shape was rejected.
|
|
251
|
+
['bare read (filter oracle)', 'get', '/enduser', { filter: { fname: 'Other' } }, 403],
|
|
252
|
+
['bare read (mdbFilter oracle)', 'get', '/enduser', { mdbFilter: { fname: { $regex: '^Oth' } } }, 403],
|
|
253
|
+
];
|
|
254
|
+
_d = 0, denied_1 = denied;
|
|
255
|
+
_g.label = 20;
|
|
256
|
+
case 20:
|
|
257
|
+
if (!(_d < denied_1.length)) return [3 /*break*/, 23];
|
|
258
|
+
_e = denied_1[_d], label = _e[0], method = _e[1], path = _e[2], data = _e[3], expected = _e[4];
|
|
259
|
+
return [4 /*yield*/, request(scopedAuthToken, method, path, data)];
|
|
260
|
+
case 21:
|
|
261
|
+
r = _g.sent();
|
|
262
|
+
(0, testing_1.assert)(r.status === expected, "".concat(label, " returned ").concat(r.status, ": ").concat(JSON.stringify(r.body), " \u2014 expected ").concat(expected), "denied: ".concat(label, " (").concat(expected, ")"));
|
|
263
|
+
_g.label = 22;
|
|
264
|
+
case 22:
|
|
265
|
+
_d++;
|
|
266
|
+
return [3 /*break*/, 20];
|
|
267
|
+
case 23: return [4 /*yield*/, sdk.api.endusers.getOne(enduser.id)];
|
|
268
|
+
case 24:
|
|
269
|
+
afterWriteAttempts = _g.sent();
|
|
270
|
+
(0, testing_1.assert)(afterWriteAttempts.fname === 'Embeddables' && afterWriteAttempts.phone === '+15555555555', "record was mutated: ".concat(JSON.stringify({ fname: afterWriteAttempts.fname, phone: afterWriteAttempts.phone })), 'no denied write reached the record');
|
|
271
|
+
return [4 /*yield*/, request(scopedAuthToken, 'get', "/enduser/".concat(otherEnduser.id))];
|
|
272
|
+
case 25:
|
|
273
|
+
crossRead_1 = _g.sent();
|
|
274
|
+
leaked = ['email', 'phone', 'dateOfBirth', 'fields', 'fname', 'lname']
|
|
275
|
+
.filter(function (k) { var _a; return crossRead_1.status === 200 && ((_a = crossRead_1.body) === null || _a === void 0 ? void 0 : _a[k]) !== undefined; });
|
|
276
|
+
(0, testing_1.assert)(leaked.length === 0, "cross-patient read (status ".concat(crossRead_1.status, ") leaked: ").concat(leaked.join(', ')), 'a cross-patient read is reduced to non-PHI display fields');
|
|
277
|
+
return [4 /*yield*/, render_1('{{enduser.embeddablesAuthToken}}')];
|
|
278
|
+
case 26:
|
|
279
|
+
tokenA = _g.sent();
|
|
280
|
+
sessionA = new sdk_1.EnduserSession({ host: host, businessId: businessId, authToken: tokenA });
|
|
281
|
+
return [4 /*yield*/, request(tokenA, 'get', "/enduser/".concat(enduser.id))];
|
|
282
|
+
case 27:
|
|
283
|
+
preBurn = _g.sent();
|
|
284
|
+
(0, testing_1.assert)(preBurn.status === 200, "token A read returned ".concat(preBurn.status), 'token A reads its own record before the burn');
|
|
285
|
+
return [4 /*yield*/, sdk.api.endusers.generate_auth_token({ id: enduser.id })];
|
|
286
|
+
case 28:
|
|
287
|
+
portalToken = (_g.sent()).authToken;
|
|
288
|
+
return [4 /*yield*/, sessionA.refresh_session({ invalidatePreviousToken: true })];
|
|
289
|
+
case 29:
|
|
290
|
+
tokenB = (_g.sent()).authToken;
|
|
291
|
+
return [4 /*yield*/, request(tokenA, 'get', "/enduser/".concat(enduser.id))];
|
|
292
|
+
case 30:
|
|
293
|
+
postBurnA = _g.sent();
|
|
294
|
+
(0, testing_1.assert)(postBurnA.status === 401, "token A returned ".concat(postBurnA.status, " after the burn, expected 401"), 'invalidatePreviousToken blocklists token A (401)');
|
|
295
|
+
return [4 /*yield*/, request(tokenB, 'get', "/enduser/".concat(enduser.id))];
|
|
296
|
+
case 31:
|
|
297
|
+
postBurnB = _g.sent();
|
|
298
|
+
(0, testing_1.assert)(postBurnB.status === 200, "token B returned ".concat(postBurnB.status, " after the burn, expected 200"), 'token B still works after the burn');
|
|
299
|
+
return [4 /*yield*/, request(portalToken, 'get', "/enduser/".concat(enduser.id))];
|
|
300
|
+
case 32:
|
|
301
|
+
postBurnPortal = _g.sent();
|
|
302
|
+
(0, testing_1.assert)(postBurnPortal.status === 200, "separately-minted session returned ".concat(postBurnPortal.status, ", expected 200"), 'the burn is a per-token blocklist, not a blanket logout of the patient');
|
|
303
|
+
return [4 /*yield*/, new sdk_1.EnduserSession({ host: host, businessId: businessId }).api.endusers.get_otp_methods({ token: tokenA })];
|
|
304
|
+
case 33:
|
|
305
|
+
otpMethods = _g.sent();
|
|
306
|
+
(0, testing_1.assert)(otpMethods.methods.includes('email') && otpMethods.methods.includes('sms'), "otp methods for an invalidated token: ".concat(JSON.stringify(otpMethods.methods)), 'otp-methods still resolves from an invalidated token (the OTP fallback stays reachable)');
|
|
307
|
+
return [4 /*yield*/, renderToken('{{enduser.embeddablesAuthToken}}', { caller: sdkNonAdmin })];
|
|
308
|
+
case 34:
|
|
309
|
+
nonAdminToken = _g.sent();
|
|
310
|
+
(0, testing_1.assert)(nonAdminToken.id === enduser.id
|
|
311
|
+
&& JSON.stringify(nonAdminToken.sessionScopes) === JSON.stringify(['embeddables-token']), "non-admin render produced ".concat(JSON.stringify(nonAdminToken)), 'a non-admin with templates.read + endusers.read can render the field (intentional)');
|
|
312
|
+
return [3 /*break*/, 37];
|
|
313
|
+
case 35: return [4 /*yield*/, Promise.all([
|
|
314
|
+
sdk.api.endusers.deleteOne(enduser.id).catch(function () { }),
|
|
315
|
+
sdk.api.endusers.deleteOne(otherEnduser.id).catch(function () { }),
|
|
316
|
+
sdk.api.endusers.deleteOne(collisionEnduser.id).catch(function () { }),
|
|
317
|
+
])];
|
|
318
|
+
case 36:
|
|
319
|
+
_g.sent();
|
|
320
|
+
return [7 /*endfinally*/];
|
|
321
|
+
case 37: return [2 /*return*/];
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
};
|
|
326
|
+
exports.embeddables_auth_token_tests = embeddables_auth_token_tests;
|
|
327
|
+
// Allow running this test file independently
|
|
328
|
+
if (require.main === module) {
|
|
329
|
+
var sdk_2 = new sdk_1.Session({ host: host });
|
|
330
|
+
var sdkNonAdmin_1 = new sdk_1.Session({ host: host });
|
|
331
|
+
var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
332
|
+
return __generator(this, function (_a) {
|
|
333
|
+
switch (_a.label) {
|
|
334
|
+
case 0: return [4 /*yield*/, (0, setup_1.setup_tests)(sdk_2, sdkNonAdmin_1)];
|
|
335
|
+
case 1:
|
|
336
|
+
_a.sent();
|
|
337
|
+
return [4 /*yield*/, (0, exports.embeddables_auth_token_tests)({ sdk: sdk_2, sdkNonAdmin: sdkNonAdmin_1 })];
|
|
338
|
+
case 2:
|
|
339
|
+
_a.sent();
|
|
340
|
+
return [2 /*return*/];
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
}); };
|
|
344
|
+
runTests()
|
|
345
|
+
.then(function () {
|
|
346
|
+
console.log("✅ Embeddables auth token test suite completed successfully");
|
|
347
|
+
process.exit(0);
|
|
348
|
+
})
|
|
349
|
+
.catch(function (error) {
|
|
350
|
+
console.error("❌ Embeddables auth token test suite failed:", error);
|
|
351
|
+
process.exit(1);
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
//# sourceMappingURL=embeddables_auth_token.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embeddables_auth_token.test.js","sourceRoot":"","sources":["../../../../src/tests/api_tests/embeddables_auth_token.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":"AA81EA,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;AAu1FD,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,qBA4pBhD,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,qBAoExC,CAAA;AAED,eAAO,MAAM,+BAA+B,qBA4U3C,CAAA;AAED,eAAO,MAAM,gDAAgD,qBAwC5D,CAAA;AAED,eAAO,MAAM,qBAAqB,qBAwIjC,CAAA"}
|