@agent-cards/sdk 0.23.8 → 0.23.10

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/PREFLIGHT.md +7 -5
  3. package/README.md +181 -92
  4. package/dist/aci.d.ts +7 -5
  5. package/dist/aci.generated.d.ts +2 -1
  6. package/dist/aci.generated.js +14 -4
  7. package/dist/aci.js +28 -7
  8. package/dist/amadeus-checkout.generated.js +2 -2
  9. package/dist/builtin-registry.generated.js +1 -1
  10. package/dist/card-fields.generated.js +163 -9
  11. package/dist/cdp.js +79 -34
  12. package/dist/client.d.ts +61 -31
  13. package/dist/client.js +99 -42
  14. package/dist/creditguard.generated.d.ts +1 -1
  15. package/dist/creditguard.generated.js +1 -3
  16. package/dist/cse-body.d.ts +7 -6
  17. package/dist/cse-body.js +8 -7
  18. package/dist/cybersource-secure-acceptance.generated.js +4 -3
  19. package/dist/datatrans.generated.js +8 -5
  20. package/dist/elavon-converge.d.ts +1 -1
  21. package/dist/elavon-converge.generated.js +7 -4
  22. package/dist/elavon-converge.js +4 -3
  23. package/dist/fiserv.d.ts +9 -5
  24. package/dist/fiserv.generated.d.ts +3 -3
  25. package/dist/fiserv.generated.js +50 -20
  26. package/dist/fiserv.js +10 -6
  27. package/dist/payrails.d.ts +78 -18
  28. package/dist/payrails.generated.d.ts +12 -2
  29. package/dist/payrails.generated.js +213 -18
  30. package/dist/payrails.js +165 -44
  31. package/dist/pre-claim.js +51 -29
  32. package/dist/preflight-capabilities.generated.d.ts +0 -106
  33. package/dist/preflight-capabilities.generated.js +0 -153
  34. package/dist/preflight-catalog.json +61 -181
  35. package/dist/preflight-schemas.json +6 -6
  36. package/dist/preflight.generated.d.ts +0 -106
  37. package/dist/preflight.generated.js +27 -15
  38. package/dist/preparation.d.ts +2 -0
  39. package/dist/preparation.js +4 -2
  40. package/dist/prepared-processor.d.ts +19 -5
  41. package/dist/prepared-processor.js +21 -5
  42. package/dist/primer.generated.d.ts +5 -1
  43. package/dist/primer.generated.js +200 -33
  44. package/dist/registry.d.ts +18 -12
  45. package/dist/registry.js +11 -8
  46. package/dist/shiji-sts.d.ts +24 -22
  47. package/dist/shiji-sts.generated.d.ts +1 -1
  48. package/dist/shiji-sts.generated.js +12 -8
  49. package/dist/shiji-sts.js +49 -46
  50. package/dist/stripe-checkout.generated.js +146 -49
  51. package/dist/verifone.generated.js +192 -17
  52. package/dist/verifone.js +1 -1
  53. package/dist/wspay.d.ts +17 -16
  54. package/dist/wspay.generated.d.ts +6 -1
  55. package/dist/wspay.generated.js +13 -3
  56. package/dist/wspay.js +9 -11
  57. package/examples/preflight/kernel-native/README.md +1 -1
  58. package/examples/preflight/kernel-native/inventory.json +1 -19
  59. package/package.json +3 -3
@@ -5,8 +5,8 @@ export declare const SHIJI_STS_CAPABILITY = "shiji_sts_pinned_key";
5
5
  /**
6
6
  * Why a Shiji STS request was refused, reported as the `reason` of the `unsupported_checkout` event
7
7
  * and of the attachment's `unsupported` state:
8
- * shiji_sts_keep_on_file a getTokenId in the proxy's shape while Agentcard cannot yet ask the
9
- * cardholder to let a hotel keep the card to guarantee the stay
8
+ * shiji_sts_keep_on_file a getTokenId in the proxy's shape while the card-on-file policy
9
+ * refuses (the kill switch): the hotel would keep the card
10
10
  * unsupported_shiji_sts_request any other request to getTokenId or getCvvId: not the proxy's shape,
11
11
  * a query, a port, or a body the classifier cannot read
12
12
  * shiji_sts_foreign_key a card field encrypted under a key other than the pinned Shiji key
@@ -32,7 +32,7 @@ interface ShijiStsRequest {
32
32
  }
33
33
  /**
34
34
  * The verdict on a request to an STS host that the registry recognized: 'pause' for the one prompt
35
- * (a getTokenId in the proxy's shape once the card-on-file decision allows it), 'companion' for a
35
+ * (a getTokenId in the proxy's shape while the card-on-file policy asks), 'companion' for a
36
36
  * getCvvId in the proxy's shape, and 'refuse' with a reason for everything else. A classifier that
37
37
  * throws refuses.
38
38
  */
@@ -52,18 +52,19 @@ interface ServedSubstitutions {
52
52
  export declare function isShijiStsServedSubstitution(sub: unknown): sub is ServedSubstitutions;
53
53
  /**
54
54
  * The page's reviewed getCvvId keys, as the API serves them beside an approved Shiji STS set
55
- * (checkout.ts approvedShijiStsFields, `shiji_sts_companion`): the keySequence values Agentcard
56
- * reviewed as the booking page's own getCvvId key (its SPS merchant's settings.client_key).
55
+ * (checkout.ts approvedShijiStsFields, `shiji_sts_companion`): the SHA-256 (lowercase hex of its UTF-8
56
+ * bytes) of each keySequence Agentcard reviewed as the booking page's own getCvvId key (its SPS
57
+ * merchant's settings.client_key). Neither the API nor this SDK holds the key itself.
57
58
  */
58
59
  export interface ShijiStsServedCompanion {
59
- key_sequences: string[];
60
+ key_sequence_sha256: string[];
60
61
  }
61
62
  /**
62
63
  * Whether the API's `shiji_sts_companion` beside an approved Shiji STS set is one this SDK can bind
63
- * the companion getCvvId to: exactly `{ key_sequences }`, 1 to 16 non-empty keySequences of printable
64
- * ASCII. Anything else, an API that serves none included, is not acted on: the approval reads as
65
- * malformed and the getTokenId is not continued, so no card reaches Shiji while its CVV has no
66
- * reviewed key to go to.
64
+ * the companion getCvvId to: exactly `{ key_sequence_sha256 }`, 1 to 16 lowercase hex SHA-256 values.
65
+ * Anything else, an API that serves none or serves the keys themselves included, is not acted on: the
66
+ * approval reads as malformed and the getTokenId is not continued, so no card reaches Shiji while its
67
+ * CVV has no reviewed key to go to.
67
68
  */
68
69
  export declare function isShijiStsServedCompanion(value: unknown): value is ShijiStsServedCompanion;
69
70
  /** The paused request an approval was created from: the URL and body the API reviewed at create. */
@@ -75,9 +76,9 @@ export interface ShijiStsApprovedRequest {
75
76
  * The continuation of an approved getTokenId: the paused body with the device's pan and expires
76
77
  * written over the page's own at the body root (payment-core substituteShijiSts, which refuses a
77
78
  * value that is not a ciphertext under the pinned key), the device's cvv, which this body does not
78
- * carry and the runtime keeps in memory for the one companion getCvvId, and the reviewed getCvvId
79
- * keys that companion may carry it under (`companion`, the replay's shijiStsCompanion, which the
80
- * client read from the API's shiji_sts_companion).
79
+ * carry and the runtime keeps in memory for the one companion getCvvId, and the SHA-256 of the
80
+ * reviewed getCvvId keys that companion may carry it under (`companion`, the replay's
81
+ * shijiStsCompanion, which the client read from the API's shiji_sts_companion).
81
82
  *
82
83
  * Only into `approved`, the paused getTokenId the approval was created from: `url` and `body` must
83
84
  * equal it byte for byte, so the accessToken and keySequence are the ones the API reviewed at create
@@ -88,15 +89,15 @@ export interface ShijiStsApprovedRequest {
88
89
  * Null when neither URL is on an STS host, so every other processor keeps the generic swap. Throws
89
90
  * for any other body or URL, an STS URL that is not getTokenId, a substitution
90
91
  * isShijiStsServedSubstitution refuses (`sub` is whatever the approval served, of any processor's
91
- * shape), no reviewed getCvvId key to bind the companion to, and while the card-on-file decision is
92
- * open: in each case before anything continues.
92
+ * shape), no reviewed getCvvId key to bind the companion to, and while the card-on-file policy
93
+ * refuses: in each case before anything continues.
93
94
  */
94
95
  export declare function shijiStsTokenContinuation(url: string, body: string, sub: unknown, approved: ShijiStsApprovedRequest, companion?: {
95
- keySequences: readonly string[];
96
+ keySequenceSha256: readonly string[];
96
97
  }): {
97
98
  body: string;
98
99
  cvv: string;
99
- cvvKeySequences: string[];
100
+ cvvKeySequenceSha256: string[];
100
101
  } | null;
101
102
  /**
102
103
  * One attachment's getCvvId companion: at most one binding, to the getTokenId it last continued with
@@ -113,12 +114,13 @@ export declare class ShijiStsCompanions {
113
114
  /**
114
115
  * Bind the companion of `tokenRequest` (the paused getTokenId: its URL, method and body) for the
115
116
  * page `page` (the adapter's opaque id for the frame that sent it) and keep `cvv`, the device's
116
- * CVV ciphertext, for it, to go only into a getCvvId whose keySequence is one of `cvvKeySequences`
117
- * (the reviewed getCvvId keys the approval served). Replaces any earlier binding. Throws
118
- * ShijiStsError for a request that is not a getTokenId in the proxy's shape, a key list
119
- * payment-core refuses (none, empty or malformed), and while the card-on-file decision is open.
117
+ * CVV ciphertext, for it, to go only into a getCvvId whose keySequence hashes to one of
118
+ * `cvvKeySequenceSha256` (the SHA-256 of the reviewed getCvvId keys the approval served). Replaces any
119
+ * earlier binding. Throws ShijiStsError for a request that is not a getTokenId in the proxy's shape,
120
+ * a digest list payment-core refuses (none, empty or malformed), and while the card-on-file policy
121
+ * refuses.
120
122
  */
121
- bind(tokenRequest: ShijiStsRequest, page: string, cvv: string, cvvKeySequences: readonly string[], now?: number): void;
123
+ bind(tokenRequest: ShijiStsRequest, page: string, cvv: string, cvvKeySequenceSha256: readonly string[], now?: number): void;
122
124
  /** Drop the binding and the CVV ciphertext it holds. */
123
125
  release(): void;
124
126
  /**
@@ -61,7 +61,7 @@ declare function shijiStsSubstitutionsRefusal(template: any, substitutions: any)
61
61
  code: string;
62
62
  message: any;
63
63
  } | null;
64
- declare function createShijiStsCompanion(tokenRequest: any, { page, now, cvvKeySequences }?: {}): Readonly<{
64
+ declare function createShijiStsCompanion(tokenRequest: any, { page, now, cvvKeySequenceSha256 }?: {}): Readonly<{
65
65
  claim: (request: any, context?: {}) => any;
66
66
  }>;
67
67
  declare function shijiStsResponseFacts(status: any, text: any): {
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  // Generated from @agent-cards/payment-core. Do not edit.
3
- // artifact-sha256: 364c3799a825b2f0a1058cadcf9aec6c6bf63d845616a9d451f048b8baa4f8de
3
+ // artifact-sha256: 98a535f4ba13e1ee4744fb725ae47c91fd9ca650dcb37fcd9eadd92b85bf6ce1
4
4
  // src/sha256.js
5
5
  var K = /* @__PURE__ */ new Uint32Array([
6
6
  1116352408,
@@ -535,7 +535,7 @@ var SHIJI_STS_FIELDS = /* @__PURE__ */ Object.freeze({
535
535
  token: Object.freeze(["pan", "expires"]),
536
536
  cvv: Object.freeze(["cvv"])
537
537
  });
538
- var SHIJI_STS_KEEP_ON_FILE = "refuse";
538
+ var SHIJI_STS_KEEP_ON_FILE = "ask";
539
539
  var SHIJI_STS_REFUSAL_REASONS = /* @__PURE__ */ Object.freeze([
540
540
  "unsupported",
541
541
  "foreign_key",
@@ -829,16 +829,19 @@ function shijiStsSubstitutionsRefusal(template, substitutions) {
829
829
  }
830
830
  var PAGE = /^[\x21-\x7e]{1,256}$/;
831
831
  var instant = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0;
832
- var REVIEWED_KEY_SEQUENCE = /^[\x21-\x7e]{1,256}$/;
832
+ var REVIEWED_KEY_SEQUENCE_SHA256 = /^[0-9a-f]{64}$/;
833
833
  var REVIEWED_KEY_SEQUENCES_LIMIT = 16;
834
- function reviewedKeySequences(list) {
834
+ function reviewedKeySequenceSha256(list) {
835
835
  if (!Array.isArray(list) || list.length === 0 || list.length > REVIEWED_KEY_SEQUENCES_LIMIT)
836
836
  return null;
837
- if (!list.every((key) => typeof key === "string" && REVIEWED_KEY_SEQUENCE.test(key)))
837
+ if (!list.every((digest) => typeof digest === "string" && REVIEWED_KEY_SEQUENCE_SHA256.test(digest)))
838
838
  return null;
839
839
  return Object.freeze([...list]);
840
840
  }
841
- function createShijiStsCompanion(tokenRequest, { page, now, cvvKeySequences } = {}) {
841
+ function keySequenceSha256(keySequence) {
842
+ return typeof keySequence === "string" && keySequence !== "" ? sha256Hex(keySequence) : null;
843
+ }
844
+ function createShijiStsCompanion(tokenRequest, { page, now, cvvKeySequenceSha256 } = {}) {
842
845
  const policy = shijiStsKeepOnFileRefusal();
843
846
  if (policy)
844
847
  throw new ShijiStsError(policy);
@@ -849,7 +852,7 @@ function createShijiStsCompanion(tokenRequest, { page, now, cvvKeySequences } =
849
852
  throw new ShijiStsError(token.reason);
850
853
  if (typeof page !== "string" || !PAGE.test(page) || !instant(now))
851
854
  throw new ShijiStsError("unsupported");
852
- const reviewed = reviewedKeySequences(cvvKeySequences);
855
+ const reviewed = reviewedKeySequenceSha256(cvvKeySequenceSha256);
853
856
  if (!reviewed)
854
857
  throw new ShijiStsError("unsupported");
855
858
  const host = new URL(tokenRequest.url).hostname;
@@ -864,7 +867,8 @@ function createShijiStsCompanion(tokenRequest, { page, now, cvvKeySequences } =
864
867
  return cvv.reason;
865
868
  if (used)
866
869
  return "companion_used";
867
- if (new URL(request.url).hostname !== host || context.page !== boundPage || cvv.accessToken !== token.accessToken || cvv.keySequence === null || !reviewed.includes(cvv.keySequence))
870
+ const keyDigest = keySequenceSha256(cvv.keySequence);
871
+ if (new URL(request.url).hostname !== host || context.page !== boundPage || cvv.accessToken !== token.accessToken || keyDigest === null || !reviewed.includes(keyDigest))
868
872
  return "companion_unbound";
869
873
  if (!instant(context.now) || context.now < boundAt || context.now - boundAt > SHIJI_STS_COMPANION_WINDOW_MS)
870
874
  return "companion_expired";
package/dist/shiji-sts.js CHANGED
@@ -1,15 +1,16 @@
1
1
  // Shiji Payment Solutions STS, the card leg of the MyCheck Wallet V3 (Shiji Group), as the SDK sees it.
2
2
  //
3
- // La Quinta by Wyndham's booking page loads MyCheck's wallet, whose Shiji proxy (sts.proxy.v2.1.js)
4
- // encrypts the typed card with RSAES-PKCS1-v1_5 under the RSA-1024 key it hardcodes and sends one
5
- // fetch from the page:
3
+ // Wyndham's booking pages (every brand, La Quinta and Days Inn among them) load MyCheck's wallet,
4
+ // whose Shiji proxy (sts.proxy.v2.1.js) encrypts the typed card with RSAES-PKCS1-v1_5 under the
5
+ // RSA-1024 key it hardcodes and sends one fetch from the page:
6
6
  // POST https://iframe.vault.eu.prod.shijipayment.com/v1/token/getTokenId (UAT: iframe.vault.eu.uat...)
7
- // {"accessToken":"<STS token>","pan":"<b64>","expires":"<b64>","keySequence":"<clientKey>"}
8
- // and, after MyCheck's payment-methods call, the CVV the same way to /v1/token/getCvvId. The agent's
9
- // page encrypts the placeholder card. The cardholder's device encrypts the real one under the key
10
- // payment-core pins (never a key from a row, a request or a page), and the runtime swaps those
11
- // ciphertexts over the page's own, byte for byte, at the body root, so the accessToken, the
12
- // keySequence and the origin stay the page's (mode cse).
7
+ // {"accessToken":"<STS token>","pan":"<b64>","expires":"<b64>"}
8
+ // (a wallet whose merchant has a clientKey adds it as "keySequence"; Wyndham's has none) and, after
9
+ // MyCheck's payment-methods call, the CVV the same way to /v1/token/getCvvId under the merchant's
10
+ // client_key. The agent's page encrypts the placeholder card. The cardholder's device encrypts the
11
+ // real one under the key payment-core pins (never a key from a row, a request or a page), and the
12
+ // runtime swaps those ciphertexts over the page's own, byte for byte, at the body root, so the
13
+ // accessToken, the keySequence and the origin stay the page's (mode cse).
13
14
  //
14
15
  // The registry entry ships dark (capability shiji_sts_pinned_key). This build declares the
15
16
  // capability on syncRegistry, and the API serves the entry only to an org Agentcard enabled for
@@ -19,21 +20,22 @@
19
20
  // For an org in the dark launch, a POST the registry recognizes on an STS host is judged by
20
21
  // payment-core's classifier (shiji-sts.generated.ts classifyShijiStsRequest), the same rules the API
21
22
  // runs at create and the device runs before it encrypts:
22
- // - a getTokenId in the proxy's shape is the one prompt, but only once the card-on-file decision is
23
- // made: the token Shiji mints guarantees a hotel stay, so while SHIJI_STS_KEEP_ON_FILE is
24
- // 'refuse' every one is refused in the browser (shiji_sts_keep_on_file) before any create or
25
- // prompt, and the page's card never reaches Shiji. Once asked, the device's ciphertext goes only
26
- // into that paused request, byte for byte: if the page abandons it, the approval is cancelled
27
- // (merchant_request_aborted) and no later getTokenId is answered from it, because one of the
28
- // same shape can name another Shiji merchant's accessToken and keySequence;
23
+ // - a getTokenId in the proxy's shape is the one prompt: the token Shiji mints guarantees a hotel
24
+ // stay, which the cardholder consents to on the approval screen while SHIJI_STS_KEEP_ON_FILE is
25
+ // 'ask'. Set back to 'refuse' (the kill switch), every one is refused in the browser
26
+ // (shiji_sts_keep_on_file) before any create or prompt, and the page's card never reaches Shiji.
27
+ // Once asked, the device's ciphertext goes only into that paused request, byte for byte: if the
28
+ // page abandons it, the approval is cancelled (merchant_request_aborted) and no later getTokenId
29
+ // is answered from it, because one of the same shape can name another Shiji merchant's
30
+ // accessToken and keySequence;
29
31
  // - a getCvvId never prompts. It continues with the device's CVV ciphertext only when it is the
30
32
  // companion of the getTokenId this attachment continued with the Vault's ciphertexts (same host,
31
- // same page, same accessToken, a keySequence the API reviewed as that page's getCvvId key and
32
- // served with the approval, within 120 s, once), and is refused otherwise, so the agent's
33
- // placeholder CVV never rides beside a real card and the real one goes to no unreviewed key. The
34
- // binding, and the CVV ciphertext it holds, is dropped as soon as the attachment can no longer
35
- // use it: a cancel, the page, frame or target that sent the getTokenId going away, or that frame
36
- // committing a new document, which never obtained the approval;
33
+ // same page, same accessToken, a keySequence whose SHA-256 the API reviewed as that page's
34
+ // getCvvId key and served with the approval, within 120 s, once), and is refused otherwise, so
35
+ // the agent's placeholder CVV never rides beside a real card and the real one goes to no
36
+ // unreviewed key. The binding, and the CVV ciphertext it holds, is dropped as soon as the
37
+ // attachment can no longer use it: a cancel, the page, frame or target that sent the getTokenId
38
+ // going away, or that frame committing a new document, which never obtained the approval;
37
39
  // - anything else on those two URLs is refused as an unsupported checkout.
38
40
  // Autopilot never pays this processor: the API, the authority and the enclave refuse it.
39
41
  import { SHIJI_STS_COMPANION_WINDOW_MS, SHIJI_STS_PSP, ShijiStsError, classifyShijiStsRequest, createShijiStsCompanion, isShijiStsCiphertext, isShijiStsHost, shijiStsEndpoint, substituteShijiSts, } from './shiji-sts.generated.js';
@@ -50,7 +52,7 @@ const REFUSED = Object.freeze({
50
52
  });
51
53
  /**
52
54
  * The verdict on a request to an STS host that the registry recognized: 'pause' for the one prompt
53
- * (a getTokenId in the proxy's shape once the card-on-file decision allows it), 'companion' for a
55
+ * (a getTokenId in the proxy's shape while the card-on-file policy asks), 'companion' for a
54
56
  * getCvvId in the proxy's shape, and 'refuse' with a reason for everything else. A classifier that
55
57
  * throws refuses.
56
58
  */
@@ -86,32 +88,32 @@ export function isShijiStsServedSubstitution(sub) {
86
88
  return names.length === SERVED_FIELDS.length
87
89
  && SERVED_FIELDS.every((name) => isShijiStsCiphertext(fields[name]));
88
90
  }
89
- const SERVED_KEY_SEQUENCE = /^[\x21-\x7e]{1,256}$/;
91
+ const SERVED_KEY_SEQUENCE_SHA256 = /^[0-9a-f]{64}$/;
90
92
  const SERVED_KEY_SEQUENCES_LIMIT = 16;
91
93
  /**
92
94
  * Whether the API's `shiji_sts_companion` beside an approved Shiji STS set is one this SDK can bind
93
- * the companion getCvvId to: exactly `{ key_sequences }`, 1 to 16 non-empty keySequences of printable
94
- * ASCII. Anything else, an API that serves none included, is not acted on: the approval reads as
95
- * malformed and the getTokenId is not continued, so no card reaches Shiji while its CVV has no
96
- * reviewed key to go to.
95
+ * the companion getCvvId to: exactly `{ key_sequence_sha256 }`, 1 to 16 lowercase hex SHA-256 values.
96
+ * Anything else, an API that serves none or serves the keys themselves included, is not acted on: the
97
+ * approval reads as malformed and the getTokenId is not continued, so no card reaches Shiji while its
98
+ * CVV has no reviewed key to go to.
97
99
  */
98
100
  export function isShijiStsServedCompanion(value) {
99
101
  if (!value || typeof value !== 'object' || Array.isArray(value))
100
102
  return false;
101
103
  const names = Object.keys(value);
102
- if (names.length !== 1 || names[0] !== 'key_sequences')
104
+ if (names.length !== 1 || names[0] !== 'key_sequence_sha256')
103
105
  return false;
104
- const keys = value.key_sequences;
105
- return Array.isArray(keys) && keys.length > 0 && keys.length <= SERVED_KEY_SEQUENCES_LIMIT
106
- && keys.every((key) => typeof key === 'string' && SERVED_KEY_SEQUENCE.test(key));
106
+ const digests = value.key_sequence_sha256;
107
+ return Array.isArray(digests) && digests.length > 0 && digests.length <= SERVED_KEY_SEQUENCES_LIMIT
108
+ && digests.every((digest) => typeof digest === 'string' && SERVED_KEY_SEQUENCE_SHA256.test(digest));
107
109
  }
108
110
  /**
109
111
  * The continuation of an approved getTokenId: the paused body with the device's pan and expires
110
112
  * written over the page's own at the body root (payment-core substituteShijiSts, which refuses a
111
113
  * value that is not a ciphertext under the pinned key), the device's cvv, which this body does not
112
- * carry and the runtime keeps in memory for the one companion getCvvId, and the reviewed getCvvId
113
- * keys that companion may carry it under (`companion`, the replay's shijiStsCompanion, which the
114
- * client read from the API's shiji_sts_companion).
114
+ * carry and the runtime keeps in memory for the one companion getCvvId, and the SHA-256 of the
115
+ * reviewed getCvvId keys that companion may carry it under (`companion`, the replay's
116
+ * shijiStsCompanion, which the client read from the API's shiji_sts_companion).
115
117
  *
116
118
  * Only into `approved`, the paused getTokenId the approval was created from: `url` and `body` must
117
119
  * equal it byte for byte, so the accessToken and keySequence are the ones the API reviewed at create
@@ -122,8 +124,8 @@ export function isShijiStsServedCompanion(value) {
122
124
  * Null when neither URL is on an STS host, so every other processor keeps the generic swap. Throws
123
125
  * for any other body or URL, an STS URL that is not getTokenId, a substitution
124
126
  * isShijiStsServedSubstitution refuses (`sub` is whatever the approval served, of any processor's
125
- * shape), no reviewed getCvvId key to bind the companion to, and while the card-on-file decision is
126
- * open: in each case before anything continues.
127
+ * shape), no reviewed getCvvId key to bind the companion to, and while the card-on-file policy
128
+ * refuses: in each case before anything continues.
127
129
  */
128
130
  export function shijiStsTokenContinuation(url, body, sub, approved, companion) {
129
131
  if (!isShijiStsHost(url) && !isShijiStsHost(approved.url))
@@ -132,10 +134,10 @@ export function shijiStsTokenContinuation(url, body, sub, approved, companion) {
132
134
  throw new ShijiStsError('unsupported');
133
135
  if (shijiStsEndpoint(url, 'POST') !== 'token' || !isShijiStsServedSubstitution(sub))
134
136
  throw new ShijiStsError('unsupported');
135
- const keys = companion && Array.isArray(companion.keySequences) ? [...companion.keySequences] : null;
136
- if (!keys || !isShijiStsServedCompanion({ key_sequences: keys }))
137
+ const digests = companion && Array.isArray(companion.keySequenceSha256) ? [...companion.keySequenceSha256] : null;
138
+ if (!digests || !isShijiStsServedCompanion({ key_sequence_sha256: digests }))
137
139
  throw new ShijiStsError('unsupported');
138
- return { body: substituteShijiSts(url, body, { pan: sub.fields.pan, expires: sub.fields.expires }), cvv: sub.fields.cvv, cvvKeySequences: keys };
140
+ return { body: substituteShijiSts(url, body, { pan: sub.fields.pan, expires: sub.fields.expires }), cvv: sub.fields.cvv, cvvKeySequenceSha256: digests };
139
141
  }
140
142
  /**
141
143
  * One attachment's getCvvId companion: at most one binding, to the getTokenId it last continued with
@@ -152,16 +154,17 @@ export class ShijiStsCompanions {
152
154
  /**
153
155
  * Bind the companion of `tokenRequest` (the paused getTokenId: its URL, method and body) for the
154
156
  * page `page` (the adapter's opaque id for the frame that sent it) and keep `cvv`, the device's
155
- * CVV ciphertext, for it, to go only into a getCvvId whose keySequence is one of `cvvKeySequences`
156
- * (the reviewed getCvvId keys the approval served). Replaces any earlier binding. Throws
157
- * ShijiStsError for a request that is not a getTokenId in the proxy's shape, a key list
158
- * payment-core refuses (none, empty or malformed), and while the card-on-file decision is open.
157
+ * CVV ciphertext, for it, to go only into a getCvvId whose keySequence hashes to one of
158
+ * `cvvKeySequenceSha256` (the SHA-256 of the reviewed getCvvId keys the approval served). Replaces any
159
+ * earlier binding. Throws ShijiStsError for a request that is not a getTokenId in the proxy's shape,
160
+ * a digest list payment-core refuses (none, empty or malformed), and while the card-on-file policy
161
+ * refuses.
159
162
  */
160
- bind(tokenRequest, page, cvv, cvvKeySequences, now = Date.now()) {
163
+ bind(tokenRequest, page, cvv, cvvKeySequenceSha256, now = Date.now()) {
161
164
  this.release();
162
165
  if (!isShijiStsCiphertext(cvv))
163
166
  throw new ShijiStsError('unsupported');
164
- const companion = createShijiStsCompanion({ url: tokenRequest.url, method: tokenRequest.method.toUpperCase(), body: tokenRequest.body }, { page, now, cvvKeySequences: Array.isArray(cvvKeySequences) ? [...cvvKeySequences] : cvvKeySequences });
167
+ const companion = createShijiStsCompanion({ url: tokenRequest.url, method: tokenRequest.method.toUpperCase(), body: tokenRequest.body }, { page, now, cvvKeySequenceSha256: Array.isArray(cvvKeySequenceSha256) ? [...cvvKeySequenceSha256] : cvvKeySequenceSha256 });
165
168
  const timer = setTimeout(() => { if (this.bound?.timer === timer)
166
169
  this.bound = null; }, SHIJI_STS_COMPANION_WINDOW_MS + 1000);
167
170
  timer.unref?.();