@wirexapp/card-reveal-web 1.1.0-beta.3 → 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 +165 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/revealElement.d.ts +69 -4
- package/dist/revealElement.d.ts.map +1 -1
- package/dist/revealElement.js +42 -0
- package/dist/revealElement.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,170 @@
|
|
|
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
|
+
|
|
139
|
+
## 1.1.0-beta.4
|
|
140
|
+
|
|
141
|
+
### Minor Changes
|
|
142
|
+
|
|
143
|
+
- 731da3e: Wallet checkout TOKEN MODE (WPAY-4431): pass the backend's short-lived top-up
|
|
144
|
+
token as `auth.checkoutToken` and the hosted checkout executes the top-up
|
|
145
|
+
itself, reporting `onExecuted` / `onExecuteFailed` (`wallet-executed` /
|
|
146
|
+
`wallet-execute-failed` on the wire) — the wallet payment token never leaves
|
|
147
|
+
the frame. Legacy tokenize-and-return (`onToken`) is unchanged without `auth`.
|
|
148
|
+
|
|
149
|
+
Token mode also brings Google Pay to desktop (`googlePayHandoff: 'qr' | 'none'`,
|
|
150
|
+
probe flag `googlePayHandoff`): the frame draws a QR that carries the checkout
|
|
151
|
+
itself — the token, the quote and the estimate's `provider` name (new init /
|
|
152
|
+
`arm()` / `update()` field) — and an Android phone opens the same checkout
|
|
153
|
+
top-level, pays and executes. Nothing is stored on the frames service and the
|
|
154
|
+
desktop never learns the outcome: hosts reconcile by their own status reads
|
|
155
|
+
after `wallet-state: handoff-pending`. `arm(quote, config, auth?, provider?)` /
|
|
156
|
+
`update(quote, config?, auth?, provider?)`; `wallet-update` carries `auth` and
|
|
157
|
+
`provider`; new `wallet-state` values `executing`, `handoff-pending`.
|
|
158
|
+
|
|
159
|
+
`buildWalletLaunchFragment` / `buildWalletLaunchUrl` (core) build the same
|
|
160
|
+
compact fragment for a Chrome Custom Tab launch (`#t=&e=&s=&p=[&r=]`); the page
|
|
161
|
+
resolves the provider block from the public BaaS config by name.
|
|
162
|
+
|
|
163
|
+
### Patch Changes
|
|
164
|
+
|
|
165
|
+
- Updated dependencies [731da3e]
|
|
166
|
+
- @wirexapp/card-sdk-core@1.1.0-beta.4
|
|
167
|
+
|
|
3
168
|
## 1.1.0-beta.3
|
|
4
169
|
|
|
5
170
|
### 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;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/revealElement.d.ts
CHANGED
|
@@ -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), `'
|
|
28
|
-
*
|
|
29
|
-
*
|
|
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
|
|
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"}
|
package/dist/revealElement.js
CHANGED
|
@@ -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;
|
|
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
|
|
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
|
|
40
|
+
"@wirexapp/card-sdk-core": "1.1.0"
|
|
41
41
|
}
|
|
42
42
|
}
|