@superbuilders/primer-tives 2.2.0 → 3.5.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.
- package/README.md +241 -816
- package/dist/client/auth/access-token.d.ts +10 -0
- package/dist/client/auth/access-token.d.ts.map +1 -0
- package/dist/client/auth/browser.d.ts +20 -0
- package/dist/client/auth/browser.d.ts.map +1 -0
- package/dist/client/auth/callback.d.ts +10 -0
- package/dist/client/auth/callback.d.ts.map +1 -0
- package/dist/client/auth/hosted-popup.d.ts +14 -0
- package/dist/client/auth/hosted-popup.d.ts.map +1 -0
- package/dist/client/auth/provider.d.ts +14 -0
- package/dist/client/auth/provider.d.ts.map +1 -0
- package/dist/client/auth/storage.d.ts +9 -0
- package/dist/client/auth/storage.d.ts.map +1 -0
- package/dist/client/create.d.ts +22 -25
- package/dist/client/create.d.ts.map +1 -1
- package/dist/client/create.type-test.d.ts +2 -0
- package/dist/client/create.type-test.d.ts.map +1 -0
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +363 -77
- package/dist/client/index.js.map +14 -10
- package/dist/client/runtime-subject.d.ts +4 -0
- package/dist/client/runtime-subject.d.ts.map +1 -0
- package/dist/client/session.d.ts +2 -2
- package/dist/client/session.d.ts.map +1 -1
- package/dist/client/transport.d.ts +6 -4
- package/dist/client/transport.d.ts.map +1 -1
- package/dist/errors.d.ts +7 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +14 -6
- package/dist/errors.js.map +3 -3
- package/dist/subject-pcis.d.ts +11 -5
- package/dist/subject-pcis.d.ts.map +1 -1
- package/dist/subject-pcis.js +39 -0
- package/dist/subject-pcis.js.map +11 -0
- package/dist/subject.d.ts +1 -2
- package/dist/subject.d.ts.map +1 -1
- package/dist/subject.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +2 -6
- package/dist/server/create-server.d.ts +0 -16
- package/dist/server/create-server.d.ts.map +0 -1
- package/dist/server/exchange.d.ts +0 -15
- package/dist/server/exchange.d.ts.map +0 -1
- package/dist/server/index.d.ts +0 -3
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/index.js +0 -142
- package/dist/server/index.js.map +0 -12
package/dist/client/index.js
CHANGED
|
@@ -3,7 +3,6 @@ import * as errors from "@superbuilders/errors";
|
|
|
3
3
|
var ErrNetwork = errors.new("network");
|
|
4
4
|
var ErrJsonParse = errors.new("json parse");
|
|
5
5
|
var ErrUnsupportedPci = errors.new("unsupported pci");
|
|
6
|
-
var ErrMissingRequiredPci = errors.new("missing required pci");
|
|
7
6
|
var ErrInvalidAccessToken = errors.new("invalid access token");
|
|
8
7
|
var ErrMalformedAccessToken = errors.new("malformed access token");
|
|
9
8
|
var ErrTokenExpired = errors.new("access token expired");
|
|
@@ -17,7 +16,12 @@ var ErrRateLimited = errors.new("rate limited");
|
|
|
17
16
|
var ErrServiceUnavailable = errors.new("service unavailable");
|
|
18
17
|
var ErrNotSerializable = errors.new("PrimerState is live in-memory state and must not be serialized or stored");
|
|
19
18
|
var ErrInvalidSubmission = errors.new("invalid submission");
|
|
20
|
-
var
|
|
19
|
+
var ErrAuthUnavailable = errors.new("auth unavailable");
|
|
20
|
+
var ErrAuthConfigInvalid = errors.new("auth config invalid");
|
|
21
|
+
var ErrAuthCallbackInvalid = errors.new("auth callback invalid");
|
|
22
|
+
var ErrAuthStateMismatch = errors.new("auth state mismatch");
|
|
23
|
+
var ErrAuthPopupBlocked = errors.new("auth popup blocked");
|
|
24
|
+
var ErrAuthCancelled = errors.new("auth cancelled");
|
|
21
25
|
var ErrSdkUpgradeRequired = errors.new("sdk upgrade required");
|
|
22
26
|
// src/contracts/content.ts
|
|
23
27
|
function inlinesToPlainText(nodes) {
|
|
@@ -333,16 +337,11 @@ function validateSubmissionForInteraction(interaction, submission) {
|
|
|
333
337
|
function submissionValidationMessage(result) {
|
|
334
338
|
return result.issues.join("; ");
|
|
335
339
|
}
|
|
336
|
-
// src/subject.ts
|
|
337
|
-
var SUBJECTS = ["math", "vocabulary", "science"];
|
|
338
|
-
// src/client/create.ts
|
|
339
|
-
import * as errors10 from "@superbuilders/errors";
|
|
340
|
-
|
|
341
340
|
// src/client/transport.ts
|
|
342
341
|
import * as errors2 from "@superbuilders/errors";
|
|
343
342
|
|
|
344
343
|
// src/version.ts
|
|
345
|
-
var SDK_VERSION = "
|
|
344
|
+
var SDK_VERSION = "3.5.0";
|
|
346
345
|
var NPM_PACKAGE_URL = "https://www.npmjs.com/package/@superbuilders/primer-tives";
|
|
347
346
|
|
|
348
347
|
// src/client/transport.ts
|
|
@@ -477,7 +476,8 @@ function createTransport(tc) {
|
|
|
477
476
|
method: "POST",
|
|
478
477
|
headers: {
|
|
479
478
|
"Content-Type": "application/json",
|
|
480
|
-
Authorization: `Bearer ${tc.accessToken}`,
|
|
479
|
+
Authorization: `Bearer ${tc.accessToken.value}`,
|
|
480
|
+
"X-Primer-Publishable-Key": tc.publishableKey,
|
|
481
481
|
"X-Primer-SDK-Version": SDK_VERSION
|
|
482
482
|
},
|
|
483
483
|
body: JSON.stringify(body),
|
|
@@ -509,7 +509,10 @@ function createTransport(tc) {
|
|
|
509
509
|
return { ok: false, error: buildSdkUpgradeRequiredError(sentinel, text, logger) };
|
|
510
510
|
}
|
|
511
511
|
logger.error("transport http error", {
|
|
512
|
-
status: res.status
|
|
512
|
+
status: res.status,
|
|
513
|
+
body: text,
|
|
514
|
+
intentKind: body.intent.kind,
|
|
515
|
+
subject: body.subject
|
|
513
516
|
});
|
|
514
517
|
return { ok: false, error: errors2.wrap(sentinel, text) };
|
|
515
518
|
}
|
|
@@ -1045,6 +1048,11 @@ function makeSession(sc) {
|
|
|
1045
1048
|
return state;
|
|
1046
1049
|
}
|
|
1047
1050
|
async function execute(intent, phase) {
|
|
1051
|
+
logger.debug("session execute", {
|
|
1052
|
+
phase,
|
|
1053
|
+
intentKind: intent.kind,
|
|
1054
|
+
subject: sc.subject
|
|
1055
|
+
});
|
|
1048
1056
|
const body = {
|
|
1049
1057
|
subject: sc.subject,
|
|
1050
1058
|
intent
|
|
@@ -1052,12 +1060,33 @@ function makeSession(sc) {
|
|
|
1052
1060
|
const result = await sc.transport(body);
|
|
1053
1061
|
if (!result.ok) {
|
|
1054
1062
|
if (isFatalError(result.error)) {
|
|
1055
|
-
logger.error("fatal transport error", {
|
|
1056
|
-
|
|
1063
|
+
logger.error("fatal transport error", {
|
|
1064
|
+
error: result.error,
|
|
1065
|
+
phase,
|
|
1066
|
+
intentKind: intent.kind
|
|
1067
|
+
});
|
|
1068
|
+
return {
|
|
1069
|
+
phase: "fatal",
|
|
1070
|
+
error: result.error,
|
|
1071
|
+
retriable: false,
|
|
1072
|
+
toJSON: poisonToJSON
|
|
1073
|
+
};
|
|
1057
1074
|
}
|
|
1075
|
+
logger.warn("retriable transport error", {
|
|
1076
|
+
error: result.error,
|
|
1077
|
+
phase,
|
|
1078
|
+
intentKind: intent.kind
|
|
1079
|
+
});
|
|
1058
1080
|
return errored(result.error, phase, intent);
|
|
1059
1081
|
}
|
|
1060
|
-
|
|
1082
|
+
const next = resolve(result.data);
|
|
1083
|
+
logger.debug("session execute resolved", {
|
|
1084
|
+
phase,
|
|
1085
|
+
intentKind: intent.kind,
|
|
1086
|
+
outcome: result.data.outcome,
|
|
1087
|
+
nextPhase: next.phase
|
|
1088
|
+
});
|
|
1089
|
+
return next;
|
|
1061
1090
|
}
|
|
1062
1091
|
function isPciSupported(pciId) {
|
|
1063
1092
|
for (const id of sc.supportedPcis) {
|
|
@@ -1104,39 +1133,222 @@ function makeSession(sc) {
|
|
|
1104
1133
|
return { execute };
|
|
1105
1134
|
}
|
|
1106
1135
|
|
|
1107
|
-
// src/
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1136
|
+
// src/client/auth/browser.ts
|
|
1137
|
+
import * as errors10 from "@superbuilders/errors";
|
|
1138
|
+
function browserStorage(options, logger) {
|
|
1139
|
+
if (options !== undefined && options.storage !== undefined) {
|
|
1140
|
+
return options.storage;
|
|
1141
|
+
}
|
|
1142
|
+
if (typeof globalThis.sessionStorage === "undefined") {
|
|
1143
|
+
logger.error("auth storage unavailable");
|
|
1144
|
+
throw ErrAuthUnavailable;
|
|
1145
|
+
}
|
|
1146
|
+
return globalThis.sessionStorage;
|
|
1147
|
+
}
|
|
1148
|
+
function currentUrl(options, logger) {
|
|
1149
|
+
if (options !== undefined && options.currentUrl !== undefined) {
|
|
1150
|
+
if (!URL.canParse(options.currentUrl)) {
|
|
1151
|
+
logger.error("auth current url invalid", { currentUrl: options.currentUrl });
|
|
1152
|
+
throw ErrAuthConfigInvalid;
|
|
1122
1153
|
}
|
|
1123
|
-
return
|
|
1154
|
+
return new URL(options.currentUrl);
|
|
1155
|
+
}
|
|
1156
|
+
if (typeof globalThis.location === "undefined") {
|
|
1157
|
+
logger.error("auth location unavailable");
|
|
1158
|
+
throw ErrAuthUnavailable;
|
|
1124
1159
|
}
|
|
1125
|
-
return
|
|
1160
|
+
return new URL(globalThis.location.href);
|
|
1126
1161
|
}
|
|
1127
|
-
function
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
missing.push(pci);
|
|
1162
|
+
function redirectUri(options, url, logger) {
|
|
1163
|
+
if (options !== undefined && options.redirectUri !== undefined) {
|
|
1164
|
+
if (!URL.canParse(options.redirectUri)) {
|
|
1165
|
+
logger.error("auth redirect uri invalid", { redirectUri: options.redirectUri });
|
|
1166
|
+
throw ErrAuthConfigInvalid;
|
|
1133
1167
|
}
|
|
1168
|
+
return options.redirectUri;
|
|
1169
|
+
}
|
|
1170
|
+
return `${url.origin}${url.pathname}${url.search}`;
|
|
1171
|
+
}
|
|
1172
|
+
function randomClientState(logger) {
|
|
1173
|
+
if (typeof globalThis.crypto === "undefined") {
|
|
1174
|
+
logger.error("auth crypto unavailable");
|
|
1175
|
+
throw ErrAuthUnavailable;
|
|
1176
|
+
}
|
|
1177
|
+
const bytes = new Uint8Array(24);
|
|
1178
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
1179
|
+
let result = "";
|
|
1180
|
+
for (const byte of bytes) {
|
|
1181
|
+
result += byte.toString(16).padStart(2, "0");
|
|
1182
|
+
}
|
|
1183
|
+
return result;
|
|
1184
|
+
}
|
|
1185
|
+
function clearCallbackHash(options, url) {
|
|
1186
|
+
if (options !== undefined && options.currentUrl !== undefined) {
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
if (typeof globalThis.history === "undefined") {
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
const cleanUrl = `${url.pathname}${url.search}`;
|
|
1193
|
+
globalThis.history.replaceState(globalThis.history.state, "", cleanUrl);
|
|
1194
|
+
}
|
|
1195
|
+
function openAuthPopup(url, options, logger) {
|
|
1196
|
+
if (typeof globalThis.open === "undefined") {
|
|
1197
|
+
logger.error("auth popup api unavailable");
|
|
1198
|
+
throw ErrAuthUnavailable;
|
|
1199
|
+
}
|
|
1200
|
+
let target = "primer-auth";
|
|
1201
|
+
if (options !== undefined && options.popupTarget !== undefined) {
|
|
1202
|
+
target = options.popupTarget;
|
|
1203
|
+
}
|
|
1204
|
+
let features = "popup,width=480,height=720";
|
|
1205
|
+
if (options !== undefined && options.popupFeatures !== undefined) {
|
|
1206
|
+
features = options.popupFeatures;
|
|
1207
|
+
}
|
|
1208
|
+
const popup = globalThis.open(url, target, features);
|
|
1209
|
+
if (popup === null) {
|
|
1210
|
+
logger.error("auth popup blocked");
|
|
1211
|
+
throw ErrAuthPopupBlocked;
|
|
1212
|
+
}
|
|
1213
|
+
return popup;
|
|
1214
|
+
}
|
|
1215
|
+
function readablePopupUrl(popup) {
|
|
1216
|
+
const result = errors10.trySync(function readLocation() {
|
|
1217
|
+
return popup.location.href;
|
|
1218
|
+
});
|
|
1219
|
+
if (result.error) {
|
|
1220
|
+
return null;
|
|
1134
1221
|
}
|
|
1135
|
-
return
|
|
1222
|
+
return result.data;
|
|
1223
|
+
}
|
|
1224
|
+
function sleep(ms) {
|
|
1225
|
+
return new Promise(function resolveLater(resolve) {
|
|
1226
|
+
setTimeout(resolve, ms);
|
|
1227
|
+
});
|
|
1136
1228
|
}
|
|
1137
1229
|
|
|
1138
|
-
// src/client/
|
|
1230
|
+
// src/client/auth/callback.ts
|
|
1231
|
+
var ACCESS_TOKEN_HASH_PARAM = "primer_access_token";
|
|
1232
|
+
var AUTH_STATUS_HASH_PARAM = "primer_auth";
|
|
1233
|
+
var AUTH_STATE_HASH_PARAM = "primer_state";
|
|
1234
|
+
var AUTH_SUCCESS = "success";
|
|
1235
|
+
var AUTH_ERROR = "error";
|
|
1236
|
+
function readAuthCallback(url, logger) {
|
|
1237
|
+
if (url.hash.length === 0) {
|
|
1238
|
+
return null;
|
|
1239
|
+
}
|
|
1240
|
+
const hash = new URLSearchParams(url.hash.slice(1));
|
|
1241
|
+
const authStatus = hash.get(AUTH_STATUS_HASH_PARAM);
|
|
1242
|
+
if (authStatus === null) {
|
|
1243
|
+
return null;
|
|
1244
|
+
}
|
|
1245
|
+
if (authStatus === AUTH_ERROR) {
|
|
1246
|
+
logger.error("auth callback returned error");
|
|
1247
|
+
throw ErrAuthCallbackInvalid;
|
|
1248
|
+
}
|
|
1249
|
+
if (authStatus !== AUTH_SUCCESS) {
|
|
1250
|
+
logger.error("auth callback status invalid", { authStatus });
|
|
1251
|
+
throw ErrAuthCallbackInvalid;
|
|
1252
|
+
}
|
|
1253
|
+
const accessToken = hash.get(ACCESS_TOKEN_HASH_PARAM);
|
|
1254
|
+
const state = hash.get(AUTH_STATE_HASH_PARAM);
|
|
1255
|
+
if (accessToken === null || accessToken.length === 0 || state === null || state.length === 0) {
|
|
1256
|
+
logger.error("auth callback missing token or state");
|
|
1257
|
+
throw ErrAuthCallbackInvalid;
|
|
1258
|
+
}
|
|
1259
|
+
return { accessToken, state };
|
|
1260
|
+
}
|
|
1261
|
+
function requireMatchingCallbackState(callback, expectedState, logger) {
|
|
1262
|
+
if (expectedState === null) {
|
|
1263
|
+
logger.error("auth callback expected state missing");
|
|
1264
|
+
throw ErrAuthCallbackInvalid;
|
|
1265
|
+
}
|
|
1266
|
+
if (callback.state !== expectedState) {
|
|
1267
|
+
logger.error("auth callback state mismatch");
|
|
1268
|
+
throw ErrAuthStateMismatch;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
// src/client/auth/hosted-popup.ts
|
|
1273
|
+
import * as errors11 from "@superbuilders/errors";
|
|
1274
|
+
var DEFAULT_POPUP_TIMEOUT_MS = 10 * 60 * 1000;
|
|
1275
|
+
var POPUP_POLL_MS = 250;
|
|
1276
|
+
function hostedAuthUrl(config) {
|
|
1277
|
+
const logger = config.logger;
|
|
1278
|
+
if (!URL.canParse(config.origin)) {
|
|
1279
|
+
logger.error("hosted auth origin invalid", { origin: config.origin });
|
|
1280
|
+
throw ErrAuthCallbackInvalid;
|
|
1281
|
+
}
|
|
1282
|
+
const authUrl = new URL("/auth/timeback", config.origin);
|
|
1283
|
+
authUrl.searchParams.set("publishableKey", config.publishableKey);
|
|
1284
|
+
authUrl.searchParams.set("redirectUri", redirectUri(config.options, config.currentUrl, logger));
|
|
1285
|
+
authUrl.searchParams.set("state", config.clientState);
|
|
1286
|
+
return authUrl.toString();
|
|
1287
|
+
}
|
|
1288
|
+
function popupTimeoutMs(options) {
|
|
1289
|
+
if (options !== undefined && options.popupTimeoutMs !== undefined) {
|
|
1290
|
+
return options.popupTimeoutMs;
|
|
1291
|
+
}
|
|
1292
|
+
return DEFAULT_POPUP_TIMEOUT_MS;
|
|
1293
|
+
}
|
|
1294
|
+
function readPopupCallback(href, config) {
|
|
1295
|
+
const logger = config.logger;
|
|
1296
|
+
if (!URL.canParse(href)) {
|
|
1297
|
+
return null;
|
|
1298
|
+
}
|
|
1299
|
+
const callbackResult = errors11.trySync(function readCallback() {
|
|
1300
|
+
return readAuthCallback(new URL(href), logger);
|
|
1301
|
+
});
|
|
1302
|
+
if (callbackResult.error) {
|
|
1303
|
+
logger.error("hosted auth popup callback invalid", { error: callbackResult.error });
|
|
1304
|
+
throw callbackResult.error;
|
|
1305
|
+
}
|
|
1306
|
+
const callback = callbackResult.data;
|
|
1307
|
+
if (callback === null) {
|
|
1308
|
+
return null;
|
|
1309
|
+
}
|
|
1310
|
+
if (callback.state !== config.clientState) {
|
|
1311
|
+
logger.error("hosted auth popup state mismatch");
|
|
1312
|
+
throw ErrAuthStateMismatch;
|
|
1313
|
+
}
|
|
1314
|
+
return callback.accessToken;
|
|
1315
|
+
}
|
|
1316
|
+
async function beginHostedPopup(config) {
|
|
1317
|
+
const logger = config.logger;
|
|
1318
|
+
const popup = openAuthPopup(hostedAuthUrl(config), config.options, logger);
|
|
1319
|
+
const expiresAt = Date.now() + popupTimeoutMs(config.options);
|
|
1320
|
+
while (Date.now() < expiresAt) {
|
|
1321
|
+
if (popup.closed) {
|
|
1322
|
+
logger.error("hosted auth popup closed");
|
|
1323
|
+
throw ErrAuthCancelled;
|
|
1324
|
+
}
|
|
1325
|
+
const href = readablePopupUrl(popup);
|
|
1326
|
+
if (href !== null) {
|
|
1327
|
+
const accessTokenResult = errors11.trySync(function readAccessToken() {
|
|
1328
|
+
return readPopupCallback(href, config);
|
|
1329
|
+
});
|
|
1330
|
+
if (accessTokenResult.error) {
|
|
1331
|
+
popup.close();
|
|
1332
|
+
logger.error("hosted auth popup failed", { error: accessTokenResult.error });
|
|
1333
|
+
throw accessTokenResult.error;
|
|
1334
|
+
}
|
|
1335
|
+
if (accessTokenResult.data !== null) {
|
|
1336
|
+
popup.close();
|
|
1337
|
+
logger.debug("hosted auth popup completed");
|
|
1338
|
+
return accessTokenResult.data;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
await sleep(POPUP_POLL_MS);
|
|
1342
|
+
}
|
|
1343
|
+
popup.close();
|
|
1344
|
+
logger.error("hosted auth popup timed out");
|
|
1345
|
+
throw ErrAuthCancelled;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
// src/client/auth/access-token.ts
|
|
1349
|
+
import * as errors12 from "@superbuilders/errors";
|
|
1139
1350
|
var ACCESS_TOKEN_PREFIX = "eyJ";
|
|
1351
|
+
var resolvedAccessTokenBrand = Symbol("primer resolved access token");
|
|
1140
1352
|
function isMalformedJws(token) {
|
|
1141
1353
|
if (!token.startsWith(ACCESS_TOKEN_PREFIX)) {
|
|
1142
1354
|
return true;
|
|
@@ -1144,53 +1356,127 @@ function isMalformedJws(token) {
|
|
|
1144
1356
|
const dotCount = token.split(".").length - 1;
|
|
1145
1357
|
return dotCount !== 2;
|
|
1146
1358
|
}
|
|
1147
|
-
function
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
supportedPcis = config.supportedPcis;
|
|
1359
|
+
function resolveAccessToken(token, logger) {
|
|
1360
|
+
if (isMalformedJws(token)) {
|
|
1361
|
+
logger.error("malformed access token", { prefix: ACCESS_TOKEN_PREFIX });
|
|
1362
|
+
throw errors12.wrap(ErrMalformedAccessToken, `token must start with '${ACCESS_TOKEN_PREFIX}' and contain two dots`);
|
|
1152
1363
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1364
|
+
return { value: token, [resolvedAccessTokenBrand]: true };
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
// src/client/auth/storage.ts
|
|
1368
|
+
var ACCESS_TOKEN_KEY_PREFIX = "primer:access-token";
|
|
1369
|
+
var AUTH_STATE_KEY_PREFIX = "primer:auth-state";
|
|
1370
|
+
function accessTokenStorageKey(publishableKey) {
|
|
1371
|
+
return `${ACCESS_TOKEN_KEY_PREFIX}:${publishableKey}`;
|
|
1372
|
+
}
|
|
1373
|
+
function authStateStorageKey(publishableKey) {
|
|
1374
|
+
return `${AUTH_STATE_KEY_PREFIX}:${publishableKey}`;
|
|
1375
|
+
}
|
|
1376
|
+
function loadStoredAccessToken(storage, publishableKey) {
|
|
1377
|
+
const token = storage.getItem(accessTokenStorageKey(publishableKey));
|
|
1378
|
+
if (token === null || token.length === 0) {
|
|
1379
|
+
return null;
|
|
1157
1380
|
}
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1381
|
+
return token;
|
|
1382
|
+
}
|
|
1383
|
+
function storeAccessToken(storage, publishableKey, accessToken) {
|
|
1384
|
+
storage.setItem(accessTokenStorageKey(publishableKey), accessToken);
|
|
1385
|
+
}
|
|
1386
|
+
function loadAuthState(storage, publishableKey) {
|
|
1387
|
+
const state = storage.getItem(authStateStorageKey(publishableKey));
|
|
1388
|
+
if (state === null || state.length === 0) {
|
|
1389
|
+
return null;
|
|
1161
1390
|
}
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1391
|
+
return state;
|
|
1392
|
+
}
|
|
1393
|
+
function storeAuthState(storage, publishableKey, state) {
|
|
1394
|
+
storage.setItem(authStateStorageKey(publishableKey), state);
|
|
1395
|
+
}
|
|
1396
|
+
function clearAuthState(storage, publishableKey) {
|
|
1397
|
+
storage.removeItem(authStateStorageKey(publishableKey));
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
// src/client/auth/provider.ts
|
|
1401
|
+
async function resolveHostedAccessToken(options) {
|
|
1402
|
+
const logger = options.logger;
|
|
1403
|
+
const storage = browserStorage(options.hostedAuth, logger);
|
|
1404
|
+
const url = currentUrl(options.hostedAuth, logger);
|
|
1405
|
+
const callback = readAuthCallback(url, logger);
|
|
1406
|
+
if (callback !== null) {
|
|
1407
|
+
requireMatchingCallbackState(callback, loadAuthState(storage, options.publishableKey), logger);
|
|
1408
|
+
storeAccessToken(storage, options.publishableKey, callback.accessToken);
|
|
1409
|
+
clearAuthState(storage, options.publishableKey);
|
|
1410
|
+
clearCallbackHash(options.hostedAuth, url);
|
|
1411
|
+
return resolveAccessToken(callback.accessToken, logger);
|
|
1412
|
+
}
|
|
1413
|
+
const stored = loadStoredAccessToken(storage, options.publishableKey);
|
|
1414
|
+
if (stored !== null) {
|
|
1415
|
+
return resolveAccessToken(stored, logger);
|
|
1416
|
+
}
|
|
1417
|
+
const clientState = randomClientState(logger);
|
|
1418
|
+
storeAuthState(storage, options.publishableKey, clientState);
|
|
1419
|
+
const accessToken = await beginHostedPopup({
|
|
1420
|
+
origin: options.origin,
|
|
1421
|
+
publishableKey: options.publishableKey,
|
|
1422
|
+
currentUrl: url,
|
|
1423
|
+
clientState,
|
|
1424
|
+
options: options.hostedAuth,
|
|
1168
1425
|
logger
|
|
1169
1426
|
});
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
transport
|
|
1178
|
-
});
|
|
1179
|
-
return s.execute({ kind: "observation" }, "observation");
|
|
1427
|
+
storeAccessToken(storage, options.publishableKey, accessToken);
|
|
1428
|
+
clearAuthState(storage, options.publishableKey);
|
|
1429
|
+
return resolveAccessToken(accessToken, logger);
|
|
1430
|
+
}
|
|
1431
|
+
async function resolveRuntimeAccessToken(options) {
|
|
1432
|
+
if (options.accessToken !== undefined) {
|
|
1433
|
+
return resolveAccessToken(options.accessToken, options.logger);
|
|
1180
1434
|
}
|
|
1181
|
-
return
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1435
|
+
return resolveHostedAccessToken(options);
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
// src/client/create.ts
|
|
1439
|
+
function supportedPcisOrEmpty(supportedPcis) {
|
|
1440
|
+
if (supportedPcis !== undefined) {
|
|
1441
|
+
return supportedPcis;
|
|
1442
|
+
}
|
|
1443
|
+
return [];
|
|
1444
|
+
}
|
|
1445
|
+
function runtimeSubject(subject) {
|
|
1446
|
+
if (subject === undefined) {
|
|
1447
|
+
return "all";
|
|
1448
|
+
}
|
|
1449
|
+
return subject;
|
|
1450
|
+
}
|
|
1451
|
+
async function create(options) {
|
|
1452
|
+
const logger = options.logger;
|
|
1453
|
+
logger.debug("create");
|
|
1454
|
+
const subject = runtimeSubject(options.subject);
|
|
1455
|
+
const accessToken = await resolveRuntimeAccessToken({
|
|
1456
|
+
accessToken: options.accessToken,
|
|
1457
|
+
publishableKey: options.publishableKey,
|
|
1458
|
+
origin: options.origin,
|
|
1459
|
+
logger
|
|
1460
|
+
});
|
|
1461
|
+
const transport = createTransport({
|
|
1462
|
+
accessToken,
|
|
1463
|
+
publishableKey: options.publishableKey,
|
|
1464
|
+
subject,
|
|
1465
|
+
origin: options.origin,
|
|
1466
|
+
fetch: options.fetch,
|
|
1467
|
+
abort: options.abort,
|
|
1468
|
+
logger
|
|
1469
|
+
});
|
|
1470
|
+
const session = makeSession({
|
|
1471
|
+
subject,
|
|
1472
|
+
supportedPcis: supportedPcisOrEmpty(options.supportedPcis),
|
|
1473
|
+
logger,
|
|
1474
|
+
transport
|
|
1475
|
+
});
|
|
1476
|
+
return session.execute({ kind: "observation" }, "observation");
|
|
1191
1477
|
}
|
|
1192
1478
|
export {
|
|
1193
1479
|
create
|
|
1194
1480
|
};
|
|
1195
1481
|
|
|
1196
|
-
//# debugId=
|
|
1482
|
+
//# debugId=F70B64A05A6012AC64756E2164756E21
|