@superbuilders/primer-tives 3.5.1 → 3.7.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 +234 -126
- package/dist/client/auth/browser.d.ts +1 -4
- package/dist/client/auth/browser.d.ts.map +1 -1
- package/dist/client/auth/hosted-popup.d.ts.map +1 -1
- package/dist/client/auth/provider.d.ts +18 -3
- package/dist/client/auth/provider.d.ts.map +1 -1
- package/dist/client/auth/storage.d.ts +2 -1
- package/dist/client/auth/storage.d.ts.map +1 -1
- package/dist/client/index.d.ts +3 -3
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +323 -165
- package/dist/client/index.js.map +10 -10
- package/dist/client/session-context.d.ts +1 -1
- package/dist/client/session-context.d.ts.map +1 -1
- package/dist/client/{create.d.ts → start.d.ts} +7 -5
- package/dist/client/start.d.ts.map +1 -0
- package/dist/client/start.type-test.d.ts +2 -0
- package/dist/client/start.type-test.d.ts.map +1 -0
- package/dist/client/types.d.ts +7 -2
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client/unauthenticated-state.d.ts +10 -0
- package/dist/client/unauthenticated-state.d.ts.map +1 -0
- package/dist/contracts/index.js +39 -1
- package/dist/contracts/index.js.map +2 -2
- package/dist/errors.js +39 -1
- package/dist/errors.js.map +2 -2
- package/dist/grade-level.js +39 -1
- package/dist/grade-level.js.map +2 -2
- package/dist/subject-pcis.js +39 -1
- package/dist/subject-pcis.js.map +2 -2
- package/dist/subject.js +39 -1
- package/dist/subject.js.map +2 -2
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/dist/client/create.d.ts.map +0 -1
- package/dist/client/create.type-test.d.ts +0 -2
- package/dist/client/create.type-test.d.ts.map +0 -1
|
@@ -8,7 +8,22 @@ type AccessTokenResolverOptions = {
|
|
|
8
8
|
readonly hostedAuth?: HostedAuthOptions;
|
|
9
9
|
readonly logger: PrimerLogger;
|
|
10
10
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
type ResolvedAccessTokenResult = {
|
|
12
|
+
readonly kind: "resolved";
|
|
13
|
+
readonly accessToken: ResolvedAccessToken;
|
|
14
|
+
};
|
|
15
|
+
type UnauthenticatedAccessTokenResult = {
|
|
16
|
+
readonly kind: "unauthenticated";
|
|
17
|
+
readonly error: Error | null;
|
|
18
|
+
};
|
|
19
|
+
type FatalAccessTokenResult = {
|
|
20
|
+
readonly kind: "fatal";
|
|
21
|
+
readonly error: Error;
|
|
22
|
+
};
|
|
23
|
+
type ExistingAccessTokenResult = ResolvedAccessTokenResult | UnauthenticatedAccessTokenResult | FatalAccessTokenResult;
|
|
24
|
+
type HostedLoginResult = ResolvedAccessTokenResult | UnauthenticatedAccessTokenResult;
|
|
25
|
+
declare function resolveExistingAccessToken(options: AccessTokenResolverOptions): ExistingAccessTokenResult;
|
|
26
|
+
declare function beginHostedLogin(options: AccessTokenResolverOptions): Promise<HostedLoginResult>;
|
|
27
|
+
export { beginHostedLogin, resolveExistingAccessToken };
|
|
28
|
+
export type { AccessTokenResolverOptions, ExistingAccessTokenResult, HostedLoginResult };
|
|
14
29
|
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/client/auth/provider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/client/auth/provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,EAIN,KAAK,iBAAiB,EACtB,MAAM,iDAAiD,CAAA;AAExD,OAAO,EAEN,KAAK,mBAAmB,EACxB,MAAM,sDAAsD,CAAA;AAS7D,KAAK,0BAA0B,GAAG;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,iBAAiB,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAC7B,CAAA;AAED,KAAK,yBAAyB,GAAG;IAChC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAA;CACzC,CAAA;AAED,KAAK,gCAAgC,GAAG;IACvC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;IAChC,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CAC5B,CAAA;AAED,KAAK,sBAAsB,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CACrB,CAAA;AAED,KAAK,yBAAyB,GAC3B,yBAAyB,GACzB,gCAAgC,GAChC,sBAAsB,CAAA;AAEzB,KAAK,iBAAiB,GAAG,yBAAyB,GAAG,gCAAgC,CAAA;AA4DrF,iBAAS,0BAA0B,CAClC,OAAO,EAAE,0BAA0B,GACjC,yBAAyB,CAe3B;AAED,iBAAe,gBAAgB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAqC/F;AAED,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,CAAA;AACvD,YAAY,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,CAAA"}
|
|
@@ -2,8 +2,9 @@ declare function accessTokenStorageKey(publishableKey: string): string;
|
|
|
2
2
|
declare function authStateStorageKey(publishableKey: string): string;
|
|
3
3
|
declare function loadStoredAccessToken(storage: Storage, publishableKey: string): string | null;
|
|
4
4
|
declare function storeAccessToken(storage: Storage, publishableKey: string, accessToken: string): void;
|
|
5
|
+
declare function clearStoredAccessToken(storage: Storage, publishableKey: string): void;
|
|
5
6
|
declare function loadAuthState(storage: Storage, publishableKey: string): string | null;
|
|
6
7
|
declare function storeAuthState(storage: Storage, publishableKey: string, state: string): void;
|
|
7
8
|
declare function clearAuthState(storage: Storage, publishableKey: string): void;
|
|
8
|
-
export { accessTokenStorageKey, authStateStorageKey, clearAuthState, loadAuthState, loadStoredAccessToken, storeAccessToken, storeAuthState };
|
|
9
|
+
export { accessTokenStorageKey, authStateStorageKey, clearAuthState, clearStoredAccessToken, loadAuthState, loadStoredAccessToken, storeAccessToken, storeAuthState };
|
|
9
10
|
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/client/auth/storage.ts"],"names":[],"mappings":"AAGA,iBAAS,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,iBAAS,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,iBAAS,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMtF;AAED,iBAAS,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAE7F;AAED,iBAAS,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM9E;AAED,iBAAS,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAErF;AAED,iBAAS,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,CAEtE;AAED,OAAO,EACN,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,cAAc,EACd,CAAA"}
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/client/auth/storage.ts"],"names":[],"mappings":"AAGA,iBAAS,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,iBAAS,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,iBAAS,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMtF;AAED,iBAAS,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAE7F;AAED,iBAAS,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,CAE9E;AAED,iBAAS,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM9E;AAED,iBAAS,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAErF;AAED,iBAAS,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,CAEtE;AAED,OAAO,EACN,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,sBAAsB,EACtB,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,cAAc,EACd,CAAA"}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type { PrimerOptions } from "./
|
|
3
|
-
export type { ChoiceState, CompletedState, ErroredState, ExtendedTextMultipleState, ExtendedTextSingleState, ExtendedTextState, FatalState, FeedbackState, InteractionState, MatchState, NonSerializable, ObservationState, OrderState, PciInteractionState, PciPendingRenderProps, PciRenderProps, PciSubmittedRenderProps, PrimerState, TextEntryState } from "./types";
|
|
1
|
+
export { start } from "./start";
|
|
2
|
+
export type { PrimerOptions } from "./start";
|
|
3
|
+
export type { ChoiceState, CompletedState, ErroredState, ExtendedTextMultipleState, ExtendedTextSingleState, ExtendedTextState, FatalState, FeedbackState, InteractionState, MatchState, NonSerializable, ObservationState, OrderState, PciInteractionState, PciPendingRenderProps, PciRenderProps, PciSubmittedRenderProps, PrimerState, TextEntryState, UnauthenticatedState } from "./types";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,0CAA0C,CAAA;AAChE,YAAY,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAA;AAE7E,YAAY,EACX,WAAW,EACX,cAAc,EACd,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,EACvB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,uBAAuB,EACvB,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,MAAM,0CAA0C,CAAA"}
|
package/dist/client/index.js
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
|
+
var __dispose = Symbol.dispose || /* @__PURE__ */ Symbol.for("Symbol.dispose");
|
|
2
|
+
var __asyncDispose = Symbol.asyncDispose || /* @__PURE__ */ Symbol.for("Symbol.asyncDispose");
|
|
3
|
+
var __using = (stack, value, async) => {
|
|
4
|
+
if (value != null) {
|
|
5
|
+
if (typeof value !== "object" && typeof value !== "function")
|
|
6
|
+
throw TypeError('Object expected to be assigned to "using" declaration');
|
|
7
|
+
var dispose;
|
|
8
|
+
if (async)
|
|
9
|
+
dispose = value[__asyncDispose];
|
|
10
|
+
if (dispose === undefined)
|
|
11
|
+
dispose = value[__dispose];
|
|
12
|
+
if (typeof dispose !== "function")
|
|
13
|
+
throw TypeError("Object not disposable");
|
|
14
|
+
stack.push([async, dispose, value]);
|
|
15
|
+
} else if (async) {
|
|
16
|
+
stack.push([async]);
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
};
|
|
20
|
+
var __callDispose = (stack, error, hasError) => {
|
|
21
|
+
var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
|
|
22
|
+
return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
|
|
23
|
+
}, fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e), next = (it) => {
|
|
24
|
+
while (it = stack.pop()) {
|
|
25
|
+
try {
|
|
26
|
+
var result = it[1] && it[1].call(it[2]);
|
|
27
|
+
if (it[0])
|
|
28
|
+
return Promise.resolve(result).then(next, (e) => (fail(e), next()));
|
|
29
|
+
} catch (e) {
|
|
30
|
+
fail(e);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (hasError)
|
|
34
|
+
throw error;
|
|
35
|
+
};
|
|
36
|
+
return next();
|
|
37
|
+
};
|
|
38
|
+
|
|
1
39
|
// src/errors.ts
|
|
2
40
|
import * as errors from "@superbuilders/errors";
|
|
3
41
|
var ErrNetwork = errors.new("network");
|
|
@@ -341,7 +379,7 @@ function submissionValidationMessage(result) {
|
|
|
341
379
|
import * as errors2 from "@superbuilders/errors";
|
|
342
380
|
|
|
343
381
|
// src/version.ts
|
|
344
|
-
var SDK_VERSION = "3.
|
|
382
|
+
var SDK_VERSION = "3.7.0";
|
|
345
383
|
var NPM_PACKAGE_URL = "https://www.npmjs.com/package/@superbuilders/primer-tives";
|
|
346
384
|
|
|
347
385
|
// src/client/transport.ts
|
|
@@ -1133,8 +1171,10 @@ function makeSession(sc) {
|
|
|
1133
1171
|
return { execute };
|
|
1134
1172
|
}
|
|
1135
1173
|
|
|
1174
|
+
// src/client/auth/provider.ts
|
|
1175
|
+
import * as errors11 from "@superbuilders/errors";
|
|
1176
|
+
|
|
1136
1177
|
// src/client/auth/browser.ts
|
|
1137
|
-
import * as errors10 from "@superbuilders/errors";
|
|
1138
1178
|
function browserStorage(options, logger) {
|
|
1139
1179
|
if (options !== undefined && options.storage !== undefined) {
|
|
1140
1180
|
return options.storage;
|
|
@@ -1182,16 +1222,6 @@ function randomClientState(logger) {
|
|
|
1182
1222
|
}
|
|
1183
1223
|
return result;
|
|
1184
1224
|
}
|
|
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
1225
|
function openAuthPopup(url, options, logger) {
|
|
1196
1226
|
if (typeof globalThis.open === "undefined") {
|
|
1197
1227
|
logger.error("auth popup api unavailable");
|
|
@@ -1212,67 +1242,12 @@ function openAuthPopup(url, options, logger) {
|
|
|
1212
1242
|
}
|
|
1213
1243
|
return popup;
|
|
1214
1244
|
}
|
|
1215
|
-
function readablePopupUrl(popup) {
|
|
1216
|
-
const result = errors10.trySync(function readLocation() {
|
|
1217
|
-
return popup.location.href;
|
|
1218
|
-
});
|
|
1219
|
-
if (result.error) {
|
|
1220
|
-
return null;
|
|
1221
|
-
}
|
|
1222
|
-
return result.data;
|
|
1223
|
-
}
|
|
1224
|
-
function sleep(ms) {
|
|
1225
|
-
return new Promise(function resolveLater(resolve) {
|
|
1226
|
-
setTimeout(resolve, ms);
|
|
1227
|
-
});
|
|
1228
|
-
}
|
|
1229
|
-
|
|
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
1245
|
|
|
1272
1246
|
// src/client/auth/hosted-popup.ts
|
|
1273
|
-
import * as errors11 from "@superbuilders/errors";
|
|
1274
1247
|
var DEFAULT_POPUP_TIMEOUT_MS = 10 * 60 * 1000;
|
|
1275
1248
|
var POPUP_POLL_MS = 250;
|
|
1249
|
+
var AUTH_MESSAGE_TYPE = "primer-tives.auth.result.v1";
|
|
1250
|
+
var AUTH_RESPONSE_MODE = "web_message";
|
|
1276
1251
|
function hostedAuthUrl(config) {
|
|
1277
1252
|
const logger = config.logger;
|
|
1278
1253
|
if (!URL.canParse(config.origin)) {
|
|
@@ -1283,6 +1258,7 @@ function hostedAuthUrl(config) {
|
|
|
1283
1258
|
authUrl.searchParams.set("publishableKey", config.publishableKey);
|
|
1284
1259
|
authUrl.searchParams.set("redirectUri", redirectUri(config.options, config.currentUrl, logger));
|
|
1285
1260
|
authUrl.searchParams.set("state", config.clientState);
|
|
1261
|
+
authUrl.searchParams.set("responseMode", AUTH_RESPONSE_MODE);
|
|
1286
1262
|
return authUrl.toString();
|
|
1287
1263
|
}
|
|
1288
1264
|
function popupTimeoutMs(options) {
|
|
@@ -1291,62 +1267,132 @@ function popupTimeoutMs(options) {
|
|
|
1291
1267
|
}
|
|
1292
1268
|
return DEFAULT_POPUP_TIMEOUT_MS;
|
|
1293
1269
|
}
|
|
1294
|
-
function
|
|
1295
|
-
|
|
1296
|
-
|
|
1270
|
+
function isRecord(value) {
|
|
1271
|
+
return typeof value === "object" && value !== null;
|
|
1272
|
+
}
|
|
1273
|
+
function stringField(value, key) {
|
|
1274
|
+
const field = value[key];
|
|
1275
|
+
if (typeof field !== "string" || field.length === 0) {
|
|
1297
1276
|
return null;
|
|
1298
1277
|
}
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
if (
|
|
1303
|
-
|
|
1304
|
-
throw callbackResult.error;
|
|
1278
|
+
return field;
|
|
1279
|
+
}
|
|
1280
|
+
function readPopupMessage(event, popup, config, expectedOrigin) {
|
|
1281
|
+
if (event.source !== popup) {
|
|
1282
|
+
return { kind: "ignore" };
|
|
1305
1283
|
}
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
return null;
|
|
1284
|
+
if (event.origin !== expectedOrigin) {
|
|
1285
|
+
return { kind: "ignore" };
|
|
1309
1286
|
}
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1287
|
+
const data = event.data;
|
|
1288
|
+
if (!isRecord(data)) {
|
|
1289
|
+
return { kind: "ignore" };
|
|
1313
1290
|
}
|
|
1314
|
-
|
|
1291
|
+
const messageType = stringField(data, "type");
|
|
1292
|
+
if (messageType !== AUTH_MESSAGE_TYPE) {
|
|
1293
|
+
return { kind: "ignore" };
|
|
1294
|
+
}
|
|
1295
|
+
const state = stringField(data, "state");
|
|
1296
|
+
if (state === null) {
|
|
1297
|
+
return { kind: "error", error: ErrAuthCallbackInvalid };
|
|
1298
|
+
}
|
|
1299
|
+
if (state !== config.clientState) {
|
|
1300
|
+
return { kind: "error", error: ErrAuthStateMismatch };
|
|
1301
|
+
}
|
|
1302
|
+
const status = stringField(data, "status");
|
|
1303
|
+
if (status === "error") {
|
|
1304
|
+
return { kind: "error", error: ErrAuthCallbackInvalid };
|
|
1305
|
+
}
|
|
1306
|
+
if (status !== "success") {
|
|
1307
|
+
return { kind: "error", error: ErrAuthCallbackInvalid };
|
|
1308
|
+
}
|
|
1309
|
+
const accessToken = stringField(data, "accessToken");
|
|
1310
|
+
if (accessToken === null) {
|
|
1311
|
+
return { kind: "error", error: ErrAuthCallbackInvalid };
|
|
1312
|
+
}
|
|
1313
|
+
return { kind: "success", accessToken };
|
|
1315
1314
|
}
|
|
1316
|
-
async function
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
logger.error("hosted auth popup failed", { error: accessTokenResult.error });
|
|
1333
|
-
throw accessTokenResult.error;
|
|
1315
|
+
async function waitForPopupMessage(popup, config, expectedOrigin) {
|
|
1316
|
+
let __stack = [];
|
|
1317
|
+
try {
|
|
1318
|
+
const logger = config.logger;
|
|
1319
|
+
const stack = __using(__stack, new AsyncDisposableStack, 1);
|
|
1320
|
+
stack.defer(function closePopup() {
|
|
1321
|
+
popup.close();
|
|
1322
|
+
});
|
|
1323
|
+
const result = await new Promise(function waitForMessage(resolve, reject) {
|
|
1324
|
+
let settled = false;
|
|
1325
|
+
function finishWithError(error) {
|
|
1326
|
+
if (settled) {
|
|
1327
|
+
return;
|
|
1328
|
+
}
|
|
1329
|
+
settled = true;
|
|
1330
|
+
reject(error);
|
|
1334
1331
|
}
|
|
1335
|
-
|
|
1336
|
-
|
|
1332
|
+
function finishWithToken(token) {
|
|
1333
|
+
if (settled) {
|
|
1334
|
+
return;
|
|
1335
|
+
}
|
|
1336
|
+
settled = true;
|
|
1337
1337
|
logger.debug("hosted auth popup completed");
|
|
1338
|
-
|
|
1338
|
+
resolve(token);
|
|
1339
1339
|
}
|
|
1340
|
-
|
|
1341
|
-
|
|
1340
|
+
const timeoutId = globalThis.setTimeout(function timeout() {
|
|
1341
|
+
logger.error("hosted auth popup timed out");
|
|
1342
|
+
finishWithError(ErrAuthCancelled);
|
|
1343
|
+
}, popupTimeoutMs(config.options));
|
|
1344
|
+
stack.defer(function clearPopupTimeout() {
|
|
1345
|
+
globalThis.clearTimeout(timeoutId);
|
|
1346
|
+
});
|
|
1347
|
+
const closedPollId = globalThis.setInterval(function checkClosed() {
|
|
1348
|
+
if (!popup.closed) {
|
|
1349
|
+
return;
|
|
1350
|
+
}
|
|
1351
|
+
logger.error("hosted auth popup closed");
|
|
1352
|
+
finishWithError(ErrAuthCancelled);
|
|
1353
|
+
}, POPUP_POLL_MS);
|
|
1354
|
+
stack.defer(function clearClosedPoll() {
|
|
1355
|
+
globalThis.clearInterval(closedPollId);
|
|
1356
|
+
});
|
|
1357
|
+
function handleMessage(event) {
|
|
1358
|
+
const result2 = readPopupMessage(event, popup, config, expectedOrigin);
|
|
1359
|
+
if (result2.kind === "ignore") {
|
|
1360
|
+
return;
|
|
1361
|
+
}
|
|
1362
|
+
if (result2.kind === "error") {
|
|
1363
|
+
logger.error("hosted auth popup failed", { error: result2.error });
|
|
1364
|
+
finishWithError(result2.error);
|
|
1365
|
+
return;
|
|
1366
|
+
}
|
|
1367
|
+
finishWithToken(result2.accessToken);
|
|
1368
|
+
}
|
|
1369
|
+
globalThis.addEventListener("message", handleMessage);
|
|
1370
|
+
stack.defer(function removeMessageListener() {
|
|
1371
|
+
globalThis.removeEventListener("message", handleMessage);
|
|
1372
|
+
});
|
|
1373
|
+
});
|
|
1374
|
+
return result;
|
|
1375
|
+
} catch (_catch) {
|
|
1376
|
+
var _err = _catch, _hasErr = 1;
|
|
1377
|
+
} finally {
|
|
1378
|
+
var _promise = __callDispose(__stack, _err, _hasErr);
|
|
1379
|
+
_promise && await _promise;
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
async function beginHostedPopup(config) {
|
|
1383
|
+
const logger = config.logger;
|
|
1384
|
+
const url = hostedAuthUrl(config);
|
|
1385
|
+
if (!URL.canParse(config.origin)) {
|
|
1386
|
+
logger.error("hosted auth origin invalid", { origin: config.origin });
|
|
1387
|
+
throw ErrAuthCallbackInvalid;
|
|
1342
1388
|
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1389
|
+
const expectedOrigin = new URL(config.origin).origin;
|
|
1390
|
+
const popup = openAuthPopup(url, config.options, logger);
|
|
1391
|
+
return waitForPopupMessage(popup, config, expectedOrigin);
|
|
1346
1392
|
}
|
|
1347
1393
|
|
|
1348
1394
|
// src/client/auth/access-token.ts
|
|
1349
|
-
import * as
|
|
1395
|
+
import * as errors10 from "@superbuilders/errors";
|
|
1350
1396
|
var ACCESS_TOKEN_PREFIX = "eyJ";
|
|
1351
1397
|
var resolvedAccessTokenBrand = Symbol("primer resolved access token");
|
|
1352
1398
|
function isMalformedJws(token) {
|
|
@@ -1359,7 +1405,7 @@ function isMalformedJws(token) {
|
|
|
1359
1405
|
function resolveAccessToken(token, logger) {
|
|
1360
1406
|
if (isMalformedJws(token)) {
|
|
1361
1407
|
logger.error("malformed access token", { prefix: ACCESS_TOKEN_PREFIX });
|
|
1362
|
-
throw
|
|
1408
|
+
throw errors10.wrap(ErrMalformedAccessToken, `token must start with '${ACCESS_TOKEN_PREFIX}' and contain two dots`);
|
|
1363
1409
|
}
|
|
1364
1410
|
return { value: token, [resolvedAccessTokenBrand]: true };
|
|
1365
1411
|
}
|
|
@@ -1383,12 +1429,8 @@ function loadStoredAccessToken(storage, publishableKey) {
|
|
|
1383
1429
|
function storeAccessToken(storage, publishableKey, accessToken) {
|
|
1384
1430
|
storage.setItem(accessTokenStorageKey(publishableKey), accessToken);
|
|
1385
1431
|
}
|
|
1386
|
-
function
|
|
1387
|
-
|
|
1388
|
-
if (state === null || state.length === 0) {
|
|
1389
|
-
return null;
|
|
1390
|
-
}
|
|
1391
|
-
return state;
|
|
1432
|
+
function clearStoredAccessToken(storage, publishableKey) {
|
|
1433
|
+
storage.removeItem(accessTokenStorageKey(publishableKey));
|
|
1392
1434
|
}
|
|
1393
1435
|
function storeAuthState(storage, publishableKey, state) {
|
|
1394
1436
|
storage.setItem(authStateStorageKey(publishableKey), state);
|
|
@@ -1398,44 +1440,119 @@ function clearAuthState(storage, publishableKey) {
|
|
|
1398
1440
|
}
|
|
1399
1441
|
|
|
1400
1442
|
// src/client/auth/provider.ts
|
|
1401
|
-
|
|
1443
|
+
function resolveProvidedAccessToken(token, logger) {
|
|
1444
|
+
const result = errors11.trySync(function resolveProvidedToken() {
|
|
1445
|
+
return resolveAccessToken(token, logger);
|
|
1446
|
+
});
|
|
1447
|
+
if (result.error) {
|
|
1448
|
+
return { kind: "fatal", error: result.error };
|
|
1449
|
+
}
|
|
1450
|
+
return { kind: "resolved", accessToken: result.data };
|
|
1451
|
+
}
|
|
1452
|
+
function resolveManagedAccessToken(token, logger) {
|
|
1453
|
+
const result = errors11.trySync(function resolveManagedToken() {
|
|
1454
|
+
return resolveAccessToken(token, logger);
|
|
1455
|
+
});
|
|
1456
|
+
if (result.error) {
|
|
1457
|
+
return { kind: "unauthenticated", error: result.error };
|
|
1458
|
+
}
|
|
1459
|
+
return { kind: "resolved", accessToken: result.data };
|
|
1460
|
+
}
|
|
1461
|
+
function readBrowserAuthContext(options) {
|
|
1402
1462
|
const logger = options.logger;
|
|
1403
|
-
const
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1463
|
+
const contextResult = errors11.trySync(function readContext() {
|
|
1464
|
+
const storage = browserStorage(options.hostedAuth, logger);
|
|
1465
|
+
const url = currentUrl(options.hostedAuth, logger);
|
|
1466
|
+
return { storage, url };
|
|
1467
|
+
});
|
|
1468
|
+
if (contextResult.error) {
|
|
1469
|
+
return { kind: "unauthenticated", error: contextResult.error };
|
|
1470
|
+
}
|
|
1471
|
+
return contextResult.data;
|
|
1472
|
+
}
|
|
1473
|
+
function resolveStoredAccessToken(context, options) {
|
|
1474
|
+
const stored = loadStoredAccessToken(context.storage, options.publishableKey);
|
|
1475
|
+
if (stored === null) {
|
|
1476
|
+
return null;
|
|
1477
|
+
}
|
|
1478
|
+
const resolved = resolveManagedAccessToken(stored, options.logger);
|
|
1479
|
+
if (resolved.kind === "unauthenticated") {
|
|
1480
|
+
clearStoredAccessToken(context.storage, options.publishableKey);
|
|
1481
|
+
}
|
|
1482
|
+
return resolved;
|
|
1483
|
+
}
|
|
1484
|
+
function resolveExistingAccessToken(options) {
|
|
1485
|
+
if (options.accessToken !== undefined) {
|
|
1486
|
+
return resolveProvidedAccessToken(options.accessToken, options.logger);
|
|
1487
|
+
}
|
|
1488
|
+
const context = readBrowserAuthContext(options);
|
|
1489
|
+
if ("kind" in context) {
|
|
1490
|
+
return context;
|
|
1491
|
+
}
|
|
1492
|
+
const stored = resolveStoredAccessToken(context, options);
|
|
1414
1493
|
if (stored !== null) {
|
|
1415
|
-
return
|
|
1494
|
+
return stored;
|
|
1495
|
+
}
|
|
1496
|
+
return { kind: "unauthenticated", error: null };
|
|
1497
|
+
}
|
|
1498
|
+
async function beginHostedLogin(options) {
|
|
1499
|
+
const logger = options.logger;
|
|
1500
|
+
const context = readBrowserAuthContext(options);
|
|
1501
|
+
if ("kind" in context) {
|
|
1502
|
+
return context;
|
|
1503
|
+
}
|
|
1504
|
+
const clientStateResult = errors11.trySync(function prepareHostedLogin() {
|
|
1505
|
+
const clientState2 = randomClientState(logger);
|
|
1506
|
+
storeAuthState(context.storage, options.publishableKey, clientState2);
|
|
1507
|
+
return clientState2;
|
|
1508
|
+
});
|
|
1509
|
+
if (clientStateResult.error) {
|
|
1510
|
+
return { kind: "unauthenticated", error: clientStateResult.error };
|
|
1416
1511
|
}
|
|
1417
|
-
const clientState =
|
|
1418
|
-
|
|
1419
|
-
const accessToken = await beginHostedPopup({
|
|
1512
|
+
const clientState = clientStateResult.data;
|
|
1513
|
+
const accessTokenResult = await errors11.try(beginHostedPopup({
|
|
1420
1514
|
origin: options.origin,
|
|
1421
1515
|
publishableKey: options.publishableKey,
|
|
1422
|
-
currentUrl: url,
|
|
1516
|
+
currentUrl: context.url,
|
|
1423
1517
|
clientState,
|
|
1424
1518
|
options: options.hostedAuth,
|
|
1425
1519
|
logger
|
|
1426
|
-
});
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1520
|
+
}));
|
|
1521
|
+
if (accessTokenResult.error) {
|
|
1522
|
+
clearAuthState(context.storage, options.publishableKey);
|
|
1523
|
+
return { kind: "unauthenticated", error: accessTokenResult.error };
|
|
1524
|
+
}
|
|
1525
|
+
const resolved = resolveManagedAccessToken(accessTokenResult.data, logger);
|
|
1526
|
+
if (resolved.kind === "unauthenticated") {
|
|
1527
|
+
clearAuthState(context.storage, options.publishableKey);
|
|
1528
|
+
return resolved;
|
|
1529
|
+
}
|
|
1530
|
+
storeAccessToken(context.storage, options.publishableKey, accessTokenResult.data);
|
|
1531
|
+
clearAuthState(context.storage, options.publishableKey);
|
|
1532
|
+
return resolved;
|
|
1430
1533
|
}
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1534
|
+
|
|
1535
|
+
// src/client/unauthenticated-state.ts
|
|
1536
|
+
function unauthenticatedState(config) {
|
|
1537
|
+
let pending;
|
|
1538
|
+
function login() {
|
|
1539
|
+
if (pending) {
|
|
1540
|
+
return pending;
|
|
1541
|
+
}
|
|
1542
|
+
pending = config.login().finally(function clearPending() {
|
|
1543
|
+
pending = undefined;
|
|
1544
|
+
});
|
|
1545
|
+
return pending;
|
|
1434
1546
|
}
|
|
1435
|
-
return
|
|
1547
|
+
return {
|
|
1548
|
+
phase: "unauthenticated",
|
|
1549
|
+
error: config.error,
|
|
1550
|
+
login,
|
|
1551
|
+
toJSON: poisonToJSON
|
|
1552
|
+
};
|
|
1436
1553
|
}
|
|
1437
1554
|
|
|
1438
|
-
// src/client/
|
|
1555
|
+
// src/client/start.ts
|
|
1439
1556
|
function supportedPcisOrEmpty(supportedPcis) {
|
|
1440
1557
|
if (supportedPcis !== undefined) {
|
|
1441
1558
|
return supportedPcis;
|
|
@@ -1448,35 +1565,76 @@ function runtimeSubject(subject) {
|
|
|
1448
1565
|
}
|
|
1449
1566
|
return subject;
|
|
1450
1567
|
}
|
|
1451
|
-
async function
|
|
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
|
-
});
|
|
1568
|
+
async function startRuntime(config, accessToken) {
|
|
1461
1569
|
const transport = createTransport({
|
|
1462
1570
|
accessToken,
|
|
1571
|
+
publishableKey: config.publishableKey,
|
|
1572
|
+
subject: config.subject,
|
|
1573
|
+
origin: config.origin,
|
|
1574
|
+
fetch: config.fetch,
|
|
1575
|
+
abort: config.abort,
|
|
1576
|
+
logger: config.logger
|
|
1577
|
+
});
|
|
1578
|
+
const session = makeSession({
|
|
1579
|
+
subject: config.subject,
|
|
1580
|
+
supportedPcis: config.supportedPcis,
|
|
1581
|
+
logger: config.logger,
|
|
1582
|
+
transport
|
|
1583
|
+
});
|
|
1584
|
+
return session.execute({ kind: "observation" }, "start");
|
|
1585
|
+
}
|
|
1586
|
+
function makeUnauthenticatedState(config, error) {
|
|
1587
|
+
return unauthenticatedState({
|
|
1588
|
+
error,
|
|
1589
|
+
login: function login() {
|
|
1590
|
+
return loginAndStart(config);
|
|
1591
|
+
}
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1594
|
+
async function loginAndStart(config) {
|
|
1595
|
+
const result = await beginHostedLogin({
|
|
1596
|
+
origin: config.origin,
|
|
1597
|
+
publishableKey: config.publishableKey,
|
|
1598
|
+
logger: config.logger
|
|
1599
|
+
});
|
|
1600
|
+
if (result.kind === "unauthenticated") {
|
|
1601
|
+
return makeUnauthenticatedState(config, result.error);
|
|
1602
|
+
}
|
|
1603
|
+
return startRuntime(config, result.accessToken);
|
|
1604
|
+
}
|
|
1605
|
+
async function start(options) {
|
|
1606
|
+
const logger = options.logger;
|
|
1607
|
+
logger.debug("start");
|
|
1608
|
+
const config = {
|
|
1463
1609
|
publishableKey: options.publishableKey,
|
|
1464
|
-
subject,
|
|
1465
1610
|
origin: options.origin,
|
|
1466
1611
|
fetch: options.fetch,
|
|
1467
1612
|
abort: options.abort,
|
|
1468
|
-
logger
|
|
1469
|
-
});
|
|
1470
|
-
const session = makeSession({
|
|
1471
|
-
subject,
|
|
1472
|
-
supportedPcis: supportedPcisOrEmpty(options.supportedPcis),
|
|
1473
1613
|
logger,
|
|
1474
|
-
|
|
1614
|
+
subject: runtimeSubject(options.subject),
|
|
1615
|
+
supportedPcis: supportedPcisOrEmpty(options.supportedPcis)
|
|
1616
|
+
};
|
|
1617
|
+
const accessToken = resolveExistingAccessToken({
|
|
1618
|
+
accessToken: options.accessToken,
|
|
1619
|
+
publishableKey: options.publishableKey,
|
|
1620
|
+
origin: options.origin,
|
|
1621
|
+
logger
|
|
1475
1622
|
});
|
|
1476
|
-
|
|
1623
|
+
if (accessToken.kind === "fatal") {
|
|
1624
|
+
return {
|
|
1625
|
+
phase: "fatal",
|
|
1626
|
+
error: accessToken.error,
|
|
1627
|
+
retriable: false,
|
|
1628
|
+
toJSON: poisonToJSON
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1631
|
+
if (accessToken.kind === "unauthenticated") {
|
|
1632
|
+
return makeUnauthenticatedState(config, accessToken.error);
|
|
1633
|
+
}
|
|
1634
|
+
return startRuntime(config, accessToken.accessToken);
|
|
1477
1635
|
}
|
|
1478
1636
|
export {
|
|
1479
|
-
|
|
1637
|
+
start
|
|
1480
1638
|
};
|
|
1481
1639
|
|
|
1482
|
-
//# debugId=
|
|
1640
|
+
//# debugId=9A3E7149C52454D064756E2164756E21
|