@wirexapp/card-reveal-web 1.1.0-beta.4 → 1.1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,141 @@
1
1
  # @wirexapp/card-reveal-web
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - d4654e9: Reveal `copy` option — `'button'` (default: the icon button, as today),
8
+ `'row'` (the whole row is one copy control: a real `<button>`, no icon, no
9
+ reserved width; the copied state shows on the value and is announced to
10
+ assistive tech) or `'none'` (no copy affordance; the value stays selectable
11
+ text). Copy still runs inside the frame and `onCopied` still carries the
12
+ field name only. Enumerated and re-validated in the frame; an older frame
13
+ ignores the option and renders the icon button.
14
+
15
+ Reveal `showLabels` option (default `true`). `false` renders no label
16
+ element at all — not an empty one — so a row is exactly as tall as its
17
+ value; the label string becomes the value's `aria-label`, and the icon copy
18
+ button's name carries the field ("Card Number: Copy"). With `copy:
19
+ 'button'` such a row is floored at the icon's hit target (`copyIconSize` +
20
+ 12px) so adjacent buttons never overlap. Replaces the `fontSizeLabel: '0px'`
21
+ / `lineHeightLabel: '0px'` workaround.
22
+
23
+ Reveal `rowStyle` option — `'plain'` (default, as today) or `'boxed'`: each
24
+ row becomes a pill drawn from the box tokens the collect inputs already use
25
+ (`colorBackground`, `colorBorder`, `borderRadius`, `borderWidth`,
26
+ `controlMinHeight`; 16px horizontal padding, `spacingUnit` vertical,
27
+ `fieldGap` between pills), so a border hugs the value instead of the
28
+ iframe. Deliberately opt-in: those tokens already reach reveal frames from
29
+ hosts that share one appearance object with collect, so honouring them on
30
+ presence would have restyled existing reveal rows.
31
+
32
+ Reveal `layout` option — `'column'` (default) or `'row'`: the frame's
33
+ fields sit side by side with equal widths, separated by the new `fieldGap`
34
+ appearance token (length; default `12px`; also the gap between `'boxed'`
35
+ pills). `fields: ['expiry', 'cvv']` with `layout: 'row'` is one frame and
36
+ one `/details` call where two single-field frames called it twice with the
37
+ same action token. Frame-wide on purpose: a mixed arrangement is two
38
+ frames, because a nested `fields` shape would not be ignorable by older
39
+ frames.
40
+
41
+ New `wordSpacing` appearance token (length grammar): extra space between
42
+ the card number's four-digit groups in the reveal frame — the value is
43
+ still chunked with single spaces, and no other row is affected. Reveal
44
+ `fields` entries are now validated against the known row names (unknown
45
+ entries are dropped instead of rendering an `undefined` label).
46
+
47
+ - 417ab29: Reveal masking — show/hide each sensitive value in place (WPAY-5064). The
48
+ masked state is per row (number, expiry, CVV, PIN; never the cardholder) and
49
+ lives in the frame; while masked the value TEXT is replaced (card number:
50
+ one glyph per digit except the last four; expiry `••/••`; CVV / PIN fully),
51
+ with the same character count so the row keeps its height. The values are
52
+ still fetched once at mount under the step-up and the copy control still
53
+ copies the real value — masking is a display aid, not a second
54
+ authorisation. Two things change the state:
55
+
56
+ - the USER, through an opt-in in-frame control: `maskToggle` (`'button'` =
57
+ eye / eye-off icon, themed by the `copyIcon*` tokens; `'text'` = a text
58
+ button from the new `show` / `hide` strings, sized to the wider word;
59
+ `'row'` = the value itself; default `'none'`), with `maskToggleByField`
60
+ overrides;
61
+ - the HOST, through `masked` at mount (`true`, or a per-row map such as
62
+ `{ cvv: true, pin: true }`) and `PciRevealElement.setMasked(boolean | map)`
63
+ later — no refetch, no new `actionToken` (host→frame event
64
+ `reveal-set-masked`, sent with the new reply-less `PciFrameChannel.post()`).
65
+
66
+ `onMaskedChange` / `reveal-masked-changed` reports the state of every
67
+ rendered maskable row (never the cardholder) after every change with
68
+ `{ masked, field?, reason }` (`'init'`,
69
+ `'user'`, `'host'`, `'timeout'`). `maskAfter` (ms, a number or a per-row map;
70
+ default never) re-masks a shown row from the frame; `onRevealRequested`
71
+ gates revealing: the toggle then only asks (`reveal-requested { field }`)
72
+ and the host reveals with `setMasked({ [field]: false })`. React: the
73
+ `masked` prop of `CardReveal` is live (forwarded in place, a map compared by
74
+ value); `onMaskedChange` and `onRevealRequested` are props. New string
75
+ `maskedPlaceholder` (the glyph; default `•`). Older frames ignore every
76
+ masking option and show the values: ship the frames first.
77
+
78
+ Reveal copy control — `copy: 'text'` renders the `copy` / `copied` strings
79
+ as a text button (the same shape set as `maskToggle`), and `copyByField`
80
+ overrides `copy` per row (`{ pin: 'none' }` keeps the icon button everywhere
81
+ but the PIN). Each entry is validated in the frame; an invalid entry leaves
82
+ that row on `copy`; older frames ignore the map. `copy: 'none'` keeps its
83
+ meaning (no control, the value stays selectable text).
84
+
85
+ Frames: the reveal presentation options are now resolved in one pure module
86
+ (`revealOptions.ts`) with unit tests; `fields` that is not an array is
87
+ ignored instead of thrown on; a row's side controls (toggle, copy) are
88
+ siblings of the cell, so `copy: 'row'` and a toggle button combine.
89
+
90
+ - 731da3e: Wallet checkout TOKEN MODE (WPAY-4431): pass the backend's short-lived top-up
91
+ token as `auth.checkoutToken` and the hosted checkout executes the top-up
92
+ itself, reporting `onExecuted` / `onExecuteFailed` (`wallet-executed` /
93
+ `wallet-execute-failed` on the wire) — the wallet payment token never leaves
94
+ the frame. Legacy tokenize-and-return (`onToken`) is unchanged without `auth`.
95
+
96
+ Token mode also brings Google Pay to desktop (`googlePayHandoff: 'qr' | 'none'`,
97
+ probe flag `googlePayHandoff`): the frame draws a QR that carries the checkout
98
+ itself — the token, the quote and the estimate's `provider` name (new init /
99
+ `arm()` / `update()` field) — and an Android phone opens the same checkout
100
+ top-level, pays and executes. Nothing is stored on the frames service and the
101
+ desktop never learns the outcome: hosts reconcile by their own status reads
102
+ after `wallet-state: handoff-pending`. `arm(quote, config, auth?, provider?)` /
103
+ `update(quote, config?, auth?, provider?)`; `wallet-update` carries `auth` and
104
+ `provider`; new `wallet-state` values `executing`, `handoff-pending`.
105
+
106
+ `buildWalletLaunchFragment` / `buildWalletLaunchUrl` (core) build the same
107
+ compact fragment for a Chrome Custom Tab launch (`#t=&e=&s=&p=[&r=]`); the page
108
+ resolves the provider block from the public BaaS config by name.
109
+
110
+ ### Patch Changes
111
+
112
+ - 274c69f: Fixed: the frames rendered as solid white rectangles in host pages that declare
113
+ `<meta name="color-scheme" content="dark">` (or `light dark` with dark
114
+ preferred) — typical of hybrid-app shells and dark-themed sites. The SDK set
115
+ `color-scheme: normal` on the iframe element; Chromium resolves `normal` from
116
+ the host's meta, so under a dark host the element became dark while the frame
117
+ document is light, and on that mismatch the browser paints the frame's canvas
118
+ opaque (CSS Color Adjust). The iframe element is now explicitly
119
+ `color-scheme: light`, matching the frame documents, which now declare
120
+ `:root { color-scheme: light }` as well — the frames stay transparent under any
121
+ host scheme. Hosts that set their dark theme through CSS alone were never
122
+ affected. The SDK change alone removes the mismatch for an updated host; the
123
+ frame-document change makes the pair explicit and independent of any meta.
124
+ - Updated dependencies [8097859]
125
+ - Updated dependencies [901cddf]
126
+ - Updated dependencies [cc46627]
127
+ - Updated dependencies [390c416]
128
+ - Updated dependencies [274c69f]
129
+ - Updated dependencies [b43affc]
130
+ - Updated dependencies [d4654e9]
131
+ - Updated dependencies [417ab29]
132
+ - Updated dependencies [1d89a12]
133
+ - Updated dependencies [5f67be4]
134
+ - Updated dependencies [33b4595]
135
+ - Updated dependencies [a629a98]
136
+ - Updated dependencies [731da3e]
137
+ - @wirexapp/card-sdk-core@1.1.0
138
+
3
139
  ## 1.1.0-beta.4
4
140
 
5
141
  ### Minor Changes
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { type PciSdkConfig } from '@wirexapp/card-sdk-core';
7
7
  import { PciRevealElement, type PciRevealElementConfig } from './revealElement.js';
8
- export type { PciRevealAuth, PciRevealElementConfig } from './revealElement.js';
8
+ export type { PciRevealAuth, PciRevealElementConfig, PciRevealMaskedChange } from './revealElement.js';
9
9
  export { PciRevealElement } from './revealElement.js';
10
10
  /** Create a reveal element bound to the given frame origin. */
11
11
  export declare const createCardReveal: (sdk: PciSdkConfig, config: PciRevealElementConfig) => PciRevealElement;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE3E,OAAO,EAAE,gBAAgB,EAAE,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEhF,YAAY,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,GAAI,KAAK,YAAY,EAAE,QAAQ,sBAAsB,KAAG,gBACzB,CAAC;AAI7D,mBAAmB,yBAAyB,CAAC;AAG7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE3E,OAAO,EAAE,gBAAgB,EAAE,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEhF,YAAY,EAAE,aAAa,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,GAAI,KAAK,YAAY,EAAE,QAAQ,sBAAsB,KAAG,gBACzB,CAAC;AAI7D,mBAAmB,yBAAyB,CAAC;AAG7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { PciAppearance, PciFrameStrings, PciRevealCopyMode, PciRevealField, PciRevealLayout, PciRevealRowStyle, PciRevealState } from '@wirexapp/card-sdk-core';
1
+ import type { PciAppearance, PciFrameStrings, PciRevealCopyByField, PciRevealCopyMode, PciRevealField, PciRevealLayout, PciRevealMaskedFields, PciRevealMaskedReason, PciRevealMaskedState, PciRevealMaskToggleByField, PciRevealMaskToggleMode, PciRevealRowStyle, PciRevealState } from '@wirexapp/card-sdk-core';
2
2
  export interface PciRevealAuth {
3
3
  getBearerToken: () => Promise<string>;
4
4
  /** Cardholder identity headers (X-User-Email / X-User-Wallet). Per-user
@@ -8,6 +8,16 @@ export interface PciRevealAuth {
8
8
  userEmail?: string;
9
9
  userWallet?: string;
10
10
  }
11
+ /** `onMaskedChange` payload: the masked state of every rendered maskable row
12
+ * (never the cardholder, so "every value true" means all hidden) after a
13
+ * change, which row the user toggled or the timer re-masked (absent for
14
+ * the mount report and for `setMasked()`), and who made the change. Field
15
+ * names, booleans and a reason — never a value. */
16
+ export interface PciRevealMaskedChange {
17
+ masked: PciRevealMaskedState;
18
+ field?: PciRevealField;
19
+ reason: PciRevealMaskedReason;
20
+ }
11
21
  export interface PciRevealElementConfig {
12
22
  cardId: string;
13
23
  /** One-shot step-up token minted by the host via the wallet-signature flow.
@@ -24,9 +34,10 @@ export interface PciRevealElementConfig {
24
34
  auth: PciRevealAuth;
25
35
  appearance?: PciAppearance;
26
36
  strings?: PciFrameStrings;
27
- /** Copy affordance: `'button'` (default, the icon button), `'row'` (the
28
- * whole row is one copy control, no icon) or `'none'`. Copy still runs
29
- * inside the frame and `onCopied` still fires in `'row'` mode. Read at
37
+ /** Copy affordance: `'button'` (default, the icon button), `'text'` (a
38
+ * text button from the `copy` / `copied` strings), `'row'` (the whole
39
+ * row is one copy control, no icon) or `'none'`. Copy still runs inside
40
+ * the frame and `onCopied` still fires in every copying mode. Read at
30
41
  * mount, like `appearance`. */
31
42
  copy?: PciRevealCopyMode;
32
43
  /** Render the label above each value (default `true`). `false` renders no
@@ -41,6 +52,36 @@ export interface PciRevealElementConfig {
41
52
  * apart) so e.g. `['expiry', 'cvv']` is one frame and one `/details`
42
53
  * call; `'column'` (default) stacks them. Read at mount. */
43
54
  layout?: PciRevealLayout;
55
+ /** Copy affordance per row, overriding `copy` for the named fields only
56
+ * (e.g. `{ pin: 'none' }`). Each entry is validated in the frame; an
57
+ * invalid one leaves that row on `copy`. Read at mount. */
58
+ copyByField?: PciRevealCopyByField;
59
+ /** Start with the values masked: `true` for every sensitive row, or a map
60
+ * of the rows to mask (`{ cvv: true, pin: true }`; default: nothing
61
+ * masked). The values are still fetched at mount under the step-up;
62
+ * masking only replaces the TEXT the frame draws (card number: all but
63
+ * the last four digits; expiry `••/••`; CVV / PIN fully; the cardholder
64
+ * row never). The copy control keeps copying the real value. The state
65
+ * is per row and lives in the frame; the user's `maskToggle` and your
66
+ * `setMasked()` both change it in place — no refetch, no new token. An
67
+ * older frame ignores it and shows the values — `onMaskedChange` reports
68
+ * the state the frame actually applied. */
69
+ masked?: boolean | PciRevealMaskedFields;
70
+ /** The in-frame show/hide control on every sensitive row (default
71
+ * `'none'`: drive masking from your own UI through `setMasked()`).
72
+ * `'button'` — an eye / eye-off icon button beside the value (before the
73
+ * copy button, same `copyIcon*` tokens); `'text'` — a text button from
74
+ * the `show` / `hide` strings; `'row'` — tapping the value toggles it
75
+ * (where the row is also the copy control, copying wins). Read at mount. */
76
+ maskToggle?: PciRevealMaskToggleMode;
77
+ /** `maskToggle` per row, overriding it for the named fields only. */
78
+ maskToggleByField?: PciRevealMaskToggleByField;
79
+ /** Re-mask a shown row after this many milliseconds (a number for every
80
+ * sensitive row, or a map per row; default: never). Counted from the
81
+ * moment the value is visible; masking it earlier cancels the timer.
82
+ * Reported through `onMaskedChange` with reason `'timeout'`. A host with
83
+ * its own policy needs none of this — re-mask through `setMasked()`. */
84
+ maskAfter?: number | Partial<Record<PciRevealField, number>>;
44
85
  onStateChange?: (state: PciRevealState) => void;
45
86
  /** The user copied a row's value inside the frame. Carries the field name
46
87
  * ONLY — never the value or anything derived from it. Intended for host
@@ -48,6 +89,17 @@ export interface PciRevealElementConfig {
48
89
  onCopied?: (event: {
49
90
  field: PciRevealField;
50
91
  }) => void;
92
+ /** The frame's masked state as applied: once at mount (confirming
93
+ * `masked`) and after every change — the user's toggle, your
94
+ * `setMasked()`, the `maskAfter` timer. */
95
+ onMaskedChange?: (event: PciRevealMaskedChange) => void;
96
+ /** Gate revealing behind your own check: when set, the in-frame toggle
97
+ * does NOT reveal a masked row — the frame reports the request here and
98
+ * the row stays masked until you call `setMasked({ [field]: false })`
99
+ * (after your step-up, biometrics, …). Hiding is never gated. */
100
+ onRevealRequested?: (event: {
101
+ field: PciRevealField;
102
+ }) => void;
51
103
  }
52
104
  /**
53
105
  * Own-card reveal element. The frame fetches PAN/expiry/CVV directly from the
@@ -57,8 +109,21 @@ export interface PciRevealElementConfig {
57
109
  export declare class PciRevealElement {
58
110
  private readonly config;
59
111
  private readonly channel;
112
+ /** `setMasked()` calls that arrived before the frame was initialized —
113
+ * the frame drops events before its init, so they are replayed after it,
114
+ * in order (the frame merges them; unchanged state is reported by nobody). */
115
+ private pendingMasked;
116
+ private initialized;
117
+ private destroyed;
60
118
  constructor(frameUrl: string, config: PciRevealElementConfig);
61
119
  mount(container: HTMLElement): Promise<void>;
120
+ /** Mask or show values in place — no refetch, no new `actionToken`.
121
+ * `true` / `false` sets every sensitive row; a map sets the rows it
122
+ * names and leaves the others (`{ cvv: false }` reveals the CVV only).
123
+ * Safe to call before `mount()` resolves (applied once the frame is
124
+ * initialized) and after `destroy()` (ignored). The frame confirms
125
+ * through `onMaskedChange` when the state actually changed. */
126
+ setMasked(masked: boolean | PciRevealMaskedFields): void;
62
127
  destroy(): void;
63
128
  }
64
129
  //# sourceMappingURL=revealElement.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"revealElement.d.ts","sourceRoot":"","sources":["../src/revealElement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,cAAc,EACf,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC;;;4DAGwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf;;;gCAG4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB;iFAC6E;IAC7E,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B;;;oCAGgC;IAChC,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB;;sDAEkD;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;+EAE2E;IAC3E,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B;;iEAE6D;IAC7D,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAChD;;qBAEiB;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,cAAc,CAAA;KAAE,KAAK,IAAI,CAAC;CACvD;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;gBAE9B,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB;IAStD,KAAK,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BlD,OAAO,IAAI,IAAI;CAGhB"}
1
+ {"version":3,"file":"revealElement.d.ts","sourceRoot":"","sources":["../src/revealElement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,EACvB,iBAAiB,EACjB,cAAc,EACf,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC;;;4DAGwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;oDAIoD;AACpD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf;;;gCAG4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB;iFAC6E;IAC7E,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B;;;;oCAIgC;IAChC,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB;;sDAEkD;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;+EAE2E;IAC3E,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B;;iEAE6D;IAC7D,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;gEAE4D;IAC5D,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC;;;;;;;;;gDAS4C;IAC5C,MAAM,CAAC,EAAE,OAAO,GAAG,qBAAqB,CAAC;IACzC;;;;;iFAK6E;IAC7E,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,0BAA0B,CAAC;IAC/C;;;;6EAIyE;IACzE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7D,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAChD;;qBAEiB;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,cAAc,CAAA;KAAE,KAAK,IAAI,CAAC;IACtD;;gDAE4C;IAC5C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACxD;;;sEAGkE;IAClE,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,cAAc,CAAA;KAAE,KAAK,IAAI,CAAC;CAChE;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C;;mFAE+E;IAC/E,OAAO,CAAC,aAAa,CAA8C;IACnE,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;gBAEd,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB;IAatD,KAAK,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAuClD;;;;;oEAKgE;IAChE,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,qBAAqB,GAAG,IAAI;IASxD,OAAO,IAAI,IAAI;CAKhB"}
@@ -6,6 +6,12 @@ import { PciFrameChannel } from '@wirexapp/card-sdk-core';
6
6
  */
7
7
  export class PciRevealElement {
8
8
  constructor(frameUrl, config) {
9
+ /** `setMasked()` calls that arrived before the frame was initialized —
10
+ * the frame drops events before its init, so they are replayed after it,
11
+ * in order (the frame merges them; unchanged state is reported by nobody). */
12
+ this.pendingMasked = [];
13
+ this.initialized = false;
14
+ this.destroyed = false;
9
15
  this.config = config;
10
16
  this.channel = new PciFrameChannel(frameUrl, {}, { allowClipboard: true });
11
17
  this.channel.onMessage(message => {
@@ -13,6 +19,11 @@ export class PciRevealElement {
13
19
  config.onStateChange?.(message.state);
14
20
  if (message.type === 'reveal-copied')
15
21
  config.onCopied?.({ field: message.field });
22
+ if (message.type === 'reveal-masked-changed') {
23
+ config.onMaskedChange?.({ masked: message.masked, field: message.field, reason: message.reason });
24
+ }
25
+ if (message.type === 'reveal-requested')
26
+ config.onRevealRequested?.({ field: message.field });
16
27
  });
17
28
  }
18
29
  async mount(container) {
@@ -38,10 +49,41 @@ export class PciRevealElement {
38
49
  showLabels: this.config.showLabels,
39
50
  rowStyle: this.config.rowStyle,
40
51
  layout: this.config.layout,
52
+ copyByField: this.config.copyByField,
53
+ masked: this.config.masked,
54
+ maskToggle: this.config.maskToggle,
55
+ maskToggleByField: this.config.maskToggleByField,
56
+ maskAfter: this.config.maskAfter,
57
+ // Revealing is the host's call exactly when it asked to hear about
58
+ // the requests.
59
+ revealGate: this.config.onRevealRequested ? 'host' : 'frame',
41
60
  },
42
61
  });
62
+ if (this.destroyed)
63
+ return;
64
+ this.initialized = true;
65
+ for (const masked of this.pendingMasked)
66
+ this.channel.post({ type: 'reveal-set-masked', masked });
67
+ this.pendingMasked = [];
68
+ }
69
+ /** Mask or show values in place — no refetch, no new `actionToken`.
70
+ * `true` / `false` sets every sensitive row; a map sets the rows it
71
+ * names and leaves the others (`{ cvv: false }` reveals the CVV only).
72
+ * Safe to call before `mount()` resolves (applied once the frame is
73
+ * initialized) and after `destroy()` (ignored). The frame confirms
74
+ * through `onMaskedChange` when the state actually changed. */
75
+ setMasked(masked) {
76
+ if (this.destroyed)
77
+ return;
78
+ if (!this.initialized) {
79
+ this.pendingMasked.push(masked);
80
+ return;
81
+ }
82
+ this.channel.post({ type: 'reveal-set-masked', masked });
43
83
  }
44
84
  destroy() {
85
+ this.destroyed = true;
86
+ this.pendingMasked = [];
45
87
  this.channel.destroy();
46
88
  }
47
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"revealElement.js","sourceRoot":"","sources":["../src/revealElement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AA6D1D;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAI3B,YAAY,QAAgB,EAAE,MAA8B;QAC1D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,IAAI,eAAe,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;YAC/B,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc;gBAAE,MAAM,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC3E,IAAI,OAAO,CAAC,IAAI,KAAK,eAAe;gBAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACpF,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,SAAsB;QAChC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;YACzB,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE;oBACJ,WAAW,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE;oBACpD,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS;oBACrC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU;iBACxC;gBACD,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;gBAC1B,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;gBACpC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY;gBACtC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;gBAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;gBAC1B,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc;gBAC1C,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU;gBAClC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;gBAC5B,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;gBACtB,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU;gBAClC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;gBAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;aAC3B;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;CACF"}
1
+ {"version":3,"file":"revealElement.js","sourceRoot":"","sources":["../src/revealElement.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirexapp/card-reveal-web",
3
- "version": "1.1.0-beta.4",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "description": "Reveal an issued card's PAN/expiry/CVV inside Wirex-served PCI iframes; values never reach the host page. CHD-free loader.",
6
6
  "license": "UNLICENSED",
@@ -37,6 +37,6 @@
37
37
  "prepublishOnly": "yarn clean && yarn build"
38
38
  },
39
39
  "dependencies": {
40
- "@wirexapp/card-sdk-core": "1.1.0-beta.4"
40
+ "@wirexapp/card-sdk-core": "1.1.0"
41
41
  }
42
42
  }