@agent-cards/sdk 0.23.5 → 0.23.7

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.
@@ -28,10 +28,14 @@
28
28
  * and holds, as every unsupported refusal does;
29
29
  * - no card_number, or an empty one, as in a payment with a stored payment_token: continue untouched;
30
30
  * - a body the adapter could not read: stop that request alone, since nothing proves it carries no card.
31
- * A request the synced registry recognizes as a card request belongs to that recognizer instead; no
32
- * build serves one today. Hosted Checkout, the same hosts without /silent/, takes the card on
33
- * CyberSource's own page, and neither adapter arms it.
31
+ * A request the synced registry recognizes as a card request belongs to the Secure Acceptance lane
32
+ * instead (below): the API serves that recognizer only to a build that declares
33
+ * `cybersource_sa_token_create` and only for a company Agentcard turned the lane on for, and it covers
34
+ * exactly the token create, POST https://<host>/silent/embedded/token/create on the production or the
35
+ * test host. Every other company, and every other /silent/ path, keeps the stop above. Hosted Checkout,
36
+ * the same hosts without /silent/, takes the card on CyberSource's own page, and neither adapter arms it.
34
37
  */
38
+ import { SECURE_ACCEPTANCE_MERCHANTS, SECURE_ACCEPTANCE_PAGE_CONTENT_TYPE, isSecureAcceptanceTokenRequest, secureAcceptanceMerchantEntry, secureAcceptanceReplyOutcome, } from './cybersource-secure-acceptance.generated.js';
35
39
  export const CYBERSOURCE_SECURE_ACCEPTANCE_REASON = 'unsupported_cybersource_secure_acceptance';
36
40
  /** Where the stopped page says the card was going. */
37
41
  export const CYBERSOURCE_SECURE_ACCEPTANCE_RECIPIENT = 'CyberSource';
@@ -212,3 +216,240 @@ function formFields(body) {
212
216
  fields.push(pair);
213
217
  return fields;
214
218
  }
219
+ // ---- The Secure Acceptance lane (dark launch) ----
220
+ //
221
+ // For a company Agentcard turned it on for, the API serves one recognizer (payment-core definitions.js,
222
+ // capability cybersource_sa_token_create) for one request: POST /silent/embedded/token/create on
223
+ // secureacceptance.cybersource.com (production) or testsecureacceptance.cybersource.com (sandbox), a
224
+ // create_payment_token at a signed amount of 0, with the merchant's signed fields and the four unsigned
225
+ // card fields. The rules that judge that request and CyberSource's reply live in payment-core and reach
226
+ // this SDK as cybersource-secure-acceptance.generated.ts; the API and the cardholder's device run the same
227
+ // ones. The lane pays the request only through a prepared checkout, approved before the agent clicks
228
+ // Save, and only as the merchant's hidden frame sends it:
229
+ // - the pre-claim gate holds a card-bearing post to that URL to a navigation of a frame (pre-claim.ts);
230
+ // a top navigation, a fetch or an XHR is stopped as an unrecognized post is;
231
+ // - the claim binds the preparation only to the request payment-core admits for the preparation's
232
+ // environment, profile id and page origin (prepared-processor.ts);
233
+ // - the cardholder's device sends the real card to CyberSource through the checkout relay, and the API
234
+ // hands back CyberSource's own reply page once neither it nor the device finds a card in it;
235
+ // - the adapters answer the paused frame navigation with that page, status 200 and its one content type
236
+ // (secureAcceptanceFrameAnswer), so Chrome commits it as CyberSource's own document and its auto-post
237
+ // reaches the merchant's receipt page in the agent's own session, as it would with no Agentcard.
238
+ // The clocks fit Arrow's page, which asks its frame 30 times, a second apart, from Save: reads every
239
+ // 500 ms for 30 s after the create; a pause with nothing being handed over 20 s after it is retired (the
240
+ // send window, amadeus.ts armSendWindow); a reply not read 45 s after the pause is an unknown outcome;
241
+ // and once the page is delivered, a merchant whose reviewed entry names its next request is watched for
242
+ // it for 10 s.
243
+ /** The processor id, as the registry and the API name it. */
244
+ export const SECURE_ACCEPTANCE_PSP = 'cybersource_secure_acceptance';
245
+ /** The dark-launch capability the API serves the Secure Acceptance recognizer behind (payment-core definitions.js). */
246
+ export const SECURE_ACCEPTANCE_CAPABILITY = 'cybersource_sa_token_create';
247
+ /** How long after the pause a paused token request may still be sent; past it, nothing being handed over, it is retired. */
248
+ export const SECURE_ACCEPTANCE_SEND_WINDOW_MS = 20_000;
249
+ /** How long after the pause CyberSource's reply may still be read; past it the outcome is unknown. */
250
+ export const SECURE_ACCEPTANCE_REPLY_WINDOW_MS = 45_000;
251
+ /** How long after the create the authorization is read every 500 ms instead of at the caller's interval. */
252
+ export const SECURE_ACCEPTANCE_FAST_POLL_MS = 30_000;
253
+ /** How long after the page is delivered the merchant's follow-up request is watched for. */
254
+ export const SECURE_ACCEPTANCE_FOLLOW_UP_MS = 10_000;
255
+ /** The one content type the paused frame's answer carries, as CyberSource serves its page. */
256
+ export const SECURE_ACCEPTANCE_ANSWER_CONTENT_TYPE = SECURE_ACCEPTANCE_PAGE_CONTENT_TYPE;
257
+ /** A CyberSource Secure Acceptance profile id: a UUID shape, 36 characters, hex in either case. */
258
+ const PROFILE_ID = /^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/;
259
+ /** This build's reviewed entries, or the ones a test passes. */
260
+ function reviewedEntries(entries) {
261
+ return entries ?? SECURE_ACCEPTANCE_MERCHANTS;
262
+ }
263
+ /** The reviewed entry that lists this profile id for this origin, through payment-core's own lookup, or null. */
264
+ function entryFor(profileId, merchantOrigin, entries) {
265
+ try {
266
+ return secureAcceptanceMerchantEntry(profileId, merchantOrigin, entries) ?? null;
267
+ }
268
+ catch {
269
+ return null;
270
+ }
271
+ }
272
+ /**
273
+ * The profile id a Secure Acceptance checkout prepares, or null when it can name none. A profile id the
274
+ * caller passes must have CyberSource's UUID shape, and is the one the bound request must carry. On the
275
+ * production host the caller may leave it out when exactly one entry this build reviewed lists the
276
+ * checkout page's origin, under exactly one profile id: that one is used, so the agent names nothing it
277
+ * cannot see. The test host has no entries (it takes only CyberSource's test cards), so a sandbox
278
+ * checkout always names its own. `entries` is for tests.
279
+ */
280
+ export function secureAcceptanceCheckoutProfile(input, entries) {
281
+ if (input.profileId !== undefined)
282
+ return typeof input.profileId === 'string' && PROFILE_ID.test(input.profileId) ? input.profileId : null;
283
+ if (input.environment !== 'production')
284
+ return null;
285
+ const listing = reviewedEntries(entries).filter((entry) => entry.environment === 'production' && entry.origins.includes(input.merchantOrigin));
286
+ if (listing.length !== 1 || listing[0].profileIds.length !== 1)
287
+ return null;
288
+ const [profileId] = listing[0].profileIds;
289
+ return typeof profileId === 'string' && PROFILE_ID.test(profileId) ? profileId : null;
290
+ }
291
+ /**
292
+ * Why a Secure Acceptance checkout may not be prepared under `merchant`, or null when it may:
293
+ * `secure_acceptance_profile_id_invalid` when it names no profile id this build can stand behind
294
+ * (secureAcceptanceCheckoutProfile), and, on the production host, `merchant_profile_mismatch` when the
295
+ * entry this build reviewed for that profile id and origin names another merchant, the one the approval
296
+ * shows. A profile id this build has not reviewed is the API's to judge (unsupported_checkout), as an
297
+ * eProtect paypageId is. `entries` is for tests.
298
+ */
299
+ export function secureAcceptanceCheckoutRefusal(input, entries) {
300
+ const profileId = secureAcceptanceCheckoutProfile(input, entries);
301
+ if (profileId === null)
302
+ return 'secure_acceptance_profile_id_invalid';
303
+ if (input.environment !== 'production')
304
+ return null;
305
+ const entry = entryFor(profileId, input.merchantOrigin, entries);
306
+ return entry && entry.merchant !== input.merchant ? 'merchant_profile_mismatch' : null;
307
+ }
308
+ /**
309
+ * Whether a paused request is the one shape the lane pays: a POST to the exact token-create URL on one of
310
+ * the two hosts (payment-core isSecureAcceptanceTokenRequest), sent as a navigation of a frame, as a
311
+ * merchant's form targeted at its hidden iframe sends it. A top navigation, a fetch and an XHR are not.
312
+ */
313
+ export function isSecureAcceptanceFramePost(request) {
314
+ if (request.navigation !== 'frame')
315
+ return false;
316
+ try {
317
+ return isSecureAcceptanceTokenRequest(request.url, String(request.method).toUpperCase()) === true;
318
+ }
319
+ catch {
320
+ return false;
321
+ }
322
+ }
323
+ /**
324
+ * The answer a paused token request gets, or null when the approved reply is not one to hand the frame:
325
+ * CyberSource's own page, byte for byte as the API stored it, with status 200 and the one content type
326
+ * CyberSource serves it with, and no other header. The page must pass payment-core's reply rule for the
327
+ * paused request (secureAcceptanceReplyOutcome: one hidden-input form posting to the receipt page the
328
+ * request signed, the request's own echoes, a masked number, a token, no card), run here with no card and
329
+ * no last four: the device and the API checked those.
330
+ */
331
+ export function secureAcceptanceFrameAnswer(request, response) {
332
+ if (!request || typeof request.url !== 'string' || typeof request.body !== 'string' || !response || typeof response.body !== 'string')
333
+ return null;
334
+ let verdict;
335
+ try {
336
+ // No card and no last four: the device and the API checked the page against the card.
337
+ verdict = secureAcceptanceReplyOutcome({ status: response.status, headers: { ...(response.headers ?? {}) }, bodyText: response.body }, { url: request.url, body: request.body }, undefined, undefined);
338
+ }
339
+ catch {
340
+ return null;
341
+ }
342
+ if (verdict?.outcome !== 'token' || verdict.page !== response.body)
343
+ return null;
344
+ return { status: 200, headers: { 'content-type': SECURE_ACCEPTANCE_ANSWER_CONTENT_TYPE }, body: response.body };
345
+ }
346
+ /**
347
+ * The request a reviewed merchant's page sends once its receipt page answered (Arrow: the payment-method
348
+ * set), for a production preparation whose profile id and origin an entry lists with one; null otherwise,
349
+ * the test host included. `entries` is for tests.
350
+ */
351
+ export function secureAcceptanceFollowUp(preparation, entries) {
352
+ if (preparation.environment !== 'production' || typeof preparation.secureAcceptanceProfileId !== 'string')
353
+ return null;
354
+ const followUp = entryFor(preparation.secureAcceptanceProfileId, preparation.merchantOrigin, entries)?.followUp;
355
+ if (!followUp || typeof followUp.method !== 'string' || typeof followUp.url !== 'string')
356
+ return null;
357
+ try {
358
+ return { method: followUp.method.toUpperCase(), url: new URL(followUp.url).href };
359
+ }
360
+ catch {
361
+ return null;
362
+ }
363
+ }
364
+ const INPUT_TAG = /<input\b((?:[^>"']|"[^"]*"|'[^']*')*)>/gi;
365
+ const ATTRIBUTE = /([^\s=/>"']+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
366
+ const NAMED_ENTITIES = { amp: '&', quot: '"', apos: "'", lt: '<', gt: '>' };
367
+ function decodeEntities(value) {
368
+ return value.replace(/&(#x[0-9a-f]{1,6}|#[0-9]{1,7}|[a-z]+);/gi, (whole, entity) => {
369
+ if (entity[0] === '#') {
370
+ const code = entity[1] === 'x' || entity[1] === 'X' ? parseInt(entity.slice(2), 16) : parseInt(entity.slice(1), 10);
371
+ return Number.isInteger(code) && code > 0 && code <= 0x10ffff ? String.fromCodePoint(code) : whole;
372
+ }
373
+ return NAMED_ENTITIES[entity.toLowerCase()] ?? whole;
374
+ });
375
+ }
376
+ /**
377
+ * The last four digits of the masked number CyberSource's reply page echoes (req_card_number, masked as
378
+ * x's and the last four), or null when the page carries no single such field. The page passed the reply
379
+ * rule before it was delivered, so this only reads it back for the follow-up event; it never carries more
380
+ * than those four digits.
381
+ */
382
+ export function secureAcceptanceReplyLast4(page) {
383
+ if (typeof page !== 'string')
384
+ return null;
385
+ const values = [];
386
+ for (const tag of page.matchAll(INPUT_TAG)) {
387
+ const attributes = new Map();
388
+ for (const attribute of tag[1].matchAll(ATTRIBUTE)) {
389
+ const name = attribute[1].toLowerCase();
390
+ if (!attributes.has(name))
391
+ attributes.set(name, decodeEntities(attribute[2] ?? attribute[3] ?? attribute[4] ?? ''));
392
+ }
393
+ if (attributes.get('name') === 'req_card_number')
394
+ values.push(attributes.get('value') ?? '');
395
+ }
396
+ return values.length === 1 ? /^[xX]{9,15}([0-9]{4})$/.exec(values[0])?.[1] ?? null : null;
397
+ }
398
+ /** A URL's origin and path, the part a follow-up request is matched on (its query is the page's own). */
399
+ function originAndPath(url) {
400
+ try {
401
+ const parsed = new URL(url);
402
+ return `${parsed.origin}${parsed.pathname}`;
403
+ }
404
+ catch {
405
+ return null;
406
+ }
407
+ }
408
+ /**
409
+ * One attachment's watch for the merchant's follow-up request after a delivered reply. Read-only: it
410
+ * pauses, changes and delays nothing. The adapters report every request the page sends (CDP
411
+ * Network.requestWillBeSent, Playwright page.on('request')) through saw(); when none matches the
412
+ * merchant's follow-up within SECURE_ACCEPTANCE_FOLLOW_UP_MS, the event `secure_acceptance_reply_unused`
413
+ * names the authorization and the masked number's last four, so the agent can find the card the merchant
414
+ * may have kept (in its saved cards, ending in those four) before it ever asks for a new checkout.
415
+ */
416
+ export class SecureAcceptanceFollowUpWatch {
417
+ onEvent;
418
+ ms;
419
+ watching = null;
420
+ constructor(onEvent, ms = SECURE_ACCEPTANCE_FOLLOW_UP_MS) {
421
+ this.onEvent = onEvent;
422
+ this.ms = ms;
423
+ }
424
+ /** Start watching for `followUp` after the reply for `authorizationId` was delivered; a watch already running ends unreported. */
425
+ begin(followUp, detail) {
426
+ this.end();
427
+ const target = originAndPath(followUp.url);
428
+ if (target === null)
429
+ return;
430
+ const timer = setTimeout(() => {
431
+ if (this.watching?.timer !== timer)
432
+ return;
433
+ this.watching = null;
434
+ this.onEvent?.({ type: 'secure_acceptance_reply_unused', detail: { authorizationId: detail.authorizationId, last4: detail.last4 } });
435
+ }, this.ms);
436
+ timer.unref?.();
437
+ this.watching = { target, method: String(followUp.method).toUpperCase(), timer };
438
+ }
439
+ /** A request the page sent: the follow-up, when it is the one being watched for, ends the watch. */
440
+ saw(method, url) {
441
+ if (!this.watching || typeof method !== 'string' || typeof url !== 'string')
442
+ return;
443
+ if (method.toUpperCase() === this.watching.method && originAndPath(url) === this.watching.target)
444
+ this.end();
445
+ }
446
+ /** True while a watch runs. */
447
+ get active() { return this.watching !== null; }
448
+ /** End the watch with no event. */
449
+ end() {
450
+ if (!this.watching)
451
+ return;
452
+ clearTimeout(this.watching.timer);
453
+ this.watching = null;
454
+ }
455
+ }
@@ -18,8 +18,8 @@ export interface EprotectMerchantPin {
18
18
  * (merchant_profile_mismatch) before any preparation exists. When this build pins the paypageId
19
19
  * too, it refuses another name first, before any network call, as a Fiserv checkout must name its
20
20
  * key pin's merchant. A paypageId this build does not pin is the API's to judge (unsupported_checkout
21
- * with no pin); none is pinned on either side yet. The pre-live host takes only the guide's test
22
- * cards and needs no pin. `pins` is for tests.
21
+ * with no pin). This build pins SmartPak Equine and Nordstrom, under those exact names. The pre-live
22
+ * host takes only the guide's test cards and needs no pin. `pins` is for tests.
23
23
  */
24
24
  export declare function eprotectCheckoutRefusal(input: {
25
25
  environment: string;
@@ -4,22 +4,61 @@ declare var EPROTECT_HOSTS: Readonly<{
4
4
  sandbox: "request.eprotect.vantivprelive.com";
5
5
  }>;
6
6
  declare var EPROTECT_SECONDARY_HOST: string;
7
- declare var EPROTECT_KEYS: Readonly<{
8
- production: Readonly<{
9
- keyId: "26455500012";
10
- exponent: "10001";
11
- modulus: "b9c7095ff203475347a932a6e11bacbb61cfb66a877158683634e5fb1dbf9923401bd7f82c21b67ffd3c82bdc64797c5e2ba4b57c68b1aaccb7fbe847da7234a21df910dfcc0aebacbbd4d36b35c0c35f7ee27358610d2e2fb2aa87d359deda0b5f4d77e31ac5ab98741da5b6052cb657087da05ad496154b8954939ee6fd463301ff15ebca94f210f4627a255a95ca8833728c1ab80b6cc3a874e4d3dce5d40f66c043ba1b042717bb9cc5d89434fa489a51c2ba9a3843b310df58c9e8a54c36cdd5fd66e76651b6fc88850b60e0739abfcf7d0d0cb44beb7e768da3bcea7e743b8c2d57edef59643f54432ccf60c49d4f5f84410ecf9c5a7af19bc5e792801";
12
- }>;
13
- sandbox: Readonly<{
14
- keyId: "1";
15
- exponent: "10001";
16
- modulus: "bc637dd74ba76507dad5af1c7ad6f97dbef5298c3b9f74caea7301347db7b4a8c37f26491863100667246fd45071f3346bf62239f9b117d06fb67861b66ad0d158beeddd2f6f28be93d846f4c8f9ba1bd7e8f186f36cab0e432f22b3d732c221a9ff00a9bfacb88b24503e2695fd7237835d4936477b21289478906a49b164f52503c20eb29f11fcbda2af94deb9a0bfde5a4589276897436315c5d664d60bf10650164f509283aed39747ad5d6cb2bbe54e1b42306e5db37dfd42dcbfcc689e0ddfe3bc9cb22ae7018e5a4a1ff39813584ac7bd6d6d65ca763f0a672da454081ea20e8b1d403316d80b9353ba396bea8962b1a7d2f775c76612d857c1f7594f";
17
- }>;
18
- }>;
7
+ declare var EPROTECT_KEY_SOURCES: any;
8
+ declare var EPROTECT_KEY_SCRIPT_MAX_BYTES: number;
19
9
  declare var EPROTECT_TEST_PANS: Readonly<Set<unknown>>;
20
10
  declare var EPROTECT_REFUSAL_CODES: readonly string[];
21
11
  declare function eprotectEnvironment(hostname: any): "production" | "sandbox" | null;
22
12
  declare function eprotectPreparationUrl(environment: any): string;
13
+ declare function eprotectKeySourceUrl(environment: any): string;
14
+ declare function eprotectScriptFacts(bytes: any): {
15
+ literals: number;
16
+ keyId?: undefined;
17
+ modulus?: undefined;
18
+ exponent?: undefined;
19
+ modulusSha256?: undefined;
20
+ maskedSha256?: undefined;
21
+ } | {
22
+ literals: number;
23
+ keyId: string;
24
+ modulus: string;
25
+ exponent: string;
26
+ modulusSha256: string;
27
+ maskedSha256: string;
28
+ };
29
+ declare function eprotectKeyScriptVerdict(environment: any, bytes: any, sources?: any): {
30
+ ok: boolean;
31
+ reason: string;
32
+ maskedSha256?: undefined;
33
+ keyId?: undefined;
34
+ modulus?: undefined;
35
+ modulusSha256?: undefined;
36
+ } | {
37
+ ok: boolean;
38
+ reason: string;
39
+ maskedSha256: string | undefined;
40
+ keyId?: undefined;
41
+ modulus?: undefined;
42
+ modulusSha256?: undefined;
43
+ } | {
44
+ ok: boolean;
45
+ keyId: string;
46
+ modulus: string;
47
+ modulusSha256: string;
48
+ maskedSha256: string;
49
+ reason?: undefined;
50
+ };
51
+ declare function readEprotectKeyScript(environment: any, bytes: any, sources?: any): Readonly<{
52
+ environment: any;
53
+ keyId: string | undefined;
54
+ modulus: string | undefined;
55
+ exponent: "10001";
56
+ modulusSha256: string | undefined;
57
+ }>;
58
+ declare function eprotectKeyReport(key: any): Readonly<{
59
+ key_id: any;
60
+ modulus_sha256: any;
61
+ }>;
23
62
  declare function isEprotectTokenRequest(url: any, method: any): boolean;
24
63
  declare function isEprotectRequest(request: any): boolean;
25
64
  declare function eprotectRequestFacts(url: any): {
@@ -35,7 +74,7 @@ declare function eprotectSecondaryAttempt(url: any): {
35
74
  paypageId: any;
36
75
  id: any;
37
76
  } | null;
38
- declare function isEprotectDeviceRequest(templateUrl: any, deviceUrl: any): boolean;
77
+ declare function isEprotectDeviceRequest(templateUrl: any, deviceUrl: any, sessionKeyId: any): boolean;
39
78
  declare function isPreparedEprotectRequest(url: any, method: any, body: any, environment: any, paypageId: any): boolean;
40
79
  declare var EPROTECT_MERCHANT_PINS: any;
41
80
  declare function eprotectMerchantPin(paypageId: any, merchantOrigin: any, pins?: any): any;
@@ -43,7 +82,7 @@ declare function eprotectMerchantRefusal(environment: any, paypageId: any, merch
43
82
  declare function defaultRandom(bytes: any): void;
44
83
  declare function eprotectEncrypt(text: any, key: any, random?: typeof defaultRandom): string;
45
84
  declare function eprotectCardRefusal(environment: any, cardNumber: any): "unsupported_environment" | "sandbox_host_requires_documented_test_card" | "invalid_card_number" | "live_host_refuses_documented_test_card" | null;
46
- declare function eprotectDeviceRequest(templateUrl: any, card: any, random?: typeof defaultRandom): {
85
+ declare function eprotectDeviceRequest(templateUrl: any, card: any, sessionKey: any, random?: typeof defaultRandom): {
47
86
  url: string;
48
87
  method: string;
49
88
  headers: {};
@@ -74,4 +113,4 @@ declare function eprotectGiveUp(url: any): {
74
113
  code: any;
75
114
  } | null;
76
115
  declare function eprotectRefusalCode(bodyText: any): any;
77
- export { EPROTECT_HOSTS, EPROTECT_KEYS, EPROTECT_MERCHANT_PINS, EPROTECT_PATH, EPROTECT_REFUSAL_CODES, EPROTECT_SECONDARY_HOST, EPROTECT_TEST_PANS, eprotectCardRefusal, eprotectDeviceRequest, eprotectEncrypt, eprotectEnvironment, eprotectGiveUp, eprotectJsonp, eprotectMerchantPin, eprotectMerchantRefusal, eprotectOutcome, eprotectPreparationUrl, eprotectRefusalCode, eprotectRequestFacts, eprotectSecondaryAttempt, isEprotectDeviceRequest, isEprotectRequest, isEprotectTokenRequest, isPreparedEprotectRequest, sanitizeEprotectRegistration };
116
+ export { EPROTECT_HOSTS, EPROTECT_KEY_SCRIPT_MAX_BYTES, EPROTECT_KEY_SOURCES, EPROTECT_MERCHANT_PINS, EPROTECT_PATH, EPROTECT_REFUSAL_CODES, EPROTECT_SECONDARY_HOST, EPROTECT_TEST_PANS, eprotectCardRefusal, eprotectDeviceRequest, eprotectEncrypt, eprotectEnvironment, eprotectGiveUp, eprotectJsonp, eprotectKeyReport, eprotectKeyScriptVerdict, eprotectKeySourceUrl, eprotectMerchantPin, eprotectMerchantRefusal, eprotectOutcome, eprotectPreparationUrl, eprotectRefusalCode, eprotectRequestFacts, eprotectScriptFacts, eprotectSecondaryAttempt, isEprotectDeviceRequest, isEprotectRequest, isEprotectTokenRequest, isPreparedEprotectRequest, readEprotectKeyScript, sanitizeEprotectRegistration };