skyflow-js 2.6.0 → 2.7.1
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 +19 -0
- package/README.md +2436 -1245
- package/dist/sdkNodeBuild/index.js +1 -1
- package/dist/sdkNodeBuild/index.js.gz +0 -0
- package/package.json +1 -1
- package/types/client/index.d.ts +3 -0
- package/types/core/constants.d.ts +1 -0
- package/types/core/external/collect/collect-container.d.ts +2 -1
- package/types/core/external/collect/compose-collect-container.d.ts +2 -1
- package/types/core/external/reveal/composable-reveal-container.d.ts +2 -1
- package/types/core/external/reveal/reveal-container.d.ts +2 -1
- package/types/core/internal/frame-element-init.d.ts +2 -2
- package/types/core-utils/reveal.d.ts +1 -1
- package/types/index-node.d.ts +1 -1
- package/types/libs/skyflow-error.d.ts +2 -0
- package/types/skyflow.d.ts +2 -1
- package/types/utils/common/index.d.ts +18 -0
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ Skyflow’s JavaScript SDK can be used to securely collect, tokenize, and reveal
|
|
|
18
18
|
- [**Securely collecting data client-side using Composable Elements**](#securely-collecting-data-client-side-using-composable-elements)
|
|
19
19
|
- [**Securely revealing data client-side**](#securely-revealing-data-client-side)
|
|
20
20
|
- [**Securely deleting data client-side**](#securely-deleting-data-client-side)
|
|
21
|
-
|
|
21
|
+
- [**Set Custom Network messages on container**](#set-custom-network-messages-on-container)
|
|
22
22
|
---
|
|
23
23
|
|
|
24
24
|
# Including Skyflow.js
|
|
@@ -1458,7 +1458,7 @@ Properties your provided when you created the element remain the same until you
|
|
|
1458
1458
|
### End to end example
|
|
1459
1459
|
```javascript
|
|
1460
1460
|
// Create a collect container.
|
|
1461
|
-
const collectContainer =
|
|
1461
|
+
const collectContainer = skyflowClient.container(Skyflow.ContainerType.COLLECT);
|
|
1462
1462
|
|
|
1463
1463
|
const stylesOptions = {
|
|
1464
1464
|
inputStyles: {
|
|
@@ -1540,853 +1540,2374 @@ cardNumberElement.update({
|
|
|
1540
1540
|
|
|
1541
1541
|
---
|
|
1542
1542
|
|
|
1543
|
-
# Securely collecting data client-side using Composable Elements
|
|
1544
|
-
|
|
1545
|
-
Composable Elements combine multiple Skyflow Elements in a single iframe, letting you create multiple Skyflow Elements in a single row. The following steps create a composable element and securely collect data through it.
|
|
1546
|
-
|
|
1547
|
-
### Step 1: Create a composable container
|
|
1548
|
-
|
|
1549
|
-
Create a container for the composable element using the `container(Skyflow.ContainerType)` method of the Skyflow client:
|
|
1550
|
-
|
|
1551
|
-
``` javascript
|
|
1552
|
-
const collectContainer = skyflow.container(Skyflow.ContainerType.COMPOSABLE,containerOptions);
|
|
1553
|
-
```
|
|
1554
|
-
The container requires an options object that contains the following keys:
|
|
1555
1543
|
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
For example: `[2,1]` means the container has two rows, with two elements in the first row and one element in the second row.
|
|
1544
|
+
## Using Skyflow File Element to upload a file
|
|
1559
1545
|
|
|
1560
|
-
|
|
1546
|
+
You can upload binary files to a vault using the Skyflow File Element. Use the following steps to securely upload a file.
|
|
1547
|
+
### Step 1: Create a container
|
|
1561
1548
|
|
|
1562
|
-
|
|
1563
|
-
3. `errorTextStyles`: CSS styles to apply if an error is encountered.
|
|
1549
|
+
Create a container for the form elements using the container(Skyflow.ContainerType) method of the Skyflow client:
|
|
1564
1550
|
|
|
1565
1551
|
```javascript
|
|
1566
|
-
const
|
|
1567
|
-
layout: [2, 1], // Required
|
|
1568
|
-
styles: { // Optional
|
|
1569
|
-
base: {
|
|
1570
|
-
border: '1px solid #DFE3EB',
|
|
1571
|
-
padding: '8px',
|
|
1572
|
-
borderRadius: '4px',
|
|
1573
|
-
margin: '12px 2px',
|
|
1574
|
-
},
|
|
1575
|
-
},
|
|
1576
|
-
errorTextStyles: { // Optional
|
|
1577
|
-
base: {
|
|
1578
|
-
color: 'red',
|
|
1579
|
-
fontFamily: '"Roboto", sans-serif'
|
|
1580
|
-
},
|
|
1581
|
-
global: {
|
|
1582
|
-
'@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
|
|
1583
|
-
}
|
|
1584
|
-
},
|
|
1585
|
-
};
|
|
1552
|
+
const container = skyflowClient.container(Skyflow.ContainerType.COLLECT)
|
|
1586
1553
|
```
|
|
1587
1554
|
|
|
1588
|
-
### Step 2: Create
|
|
1589
|
-
|
|
1555
|
+
### Step 2: Create a File Element
|
|
1556
|
+
|
|
1557
|
+
Skyflow Collect Elements are defined as follows:
|
|
1590
1558
|
|
|
1591
1559
|
```javascript
|
|
1592
|
-
const
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
placeholder: 'string', // Optional. Placeholder for the form element.
|
|
1601
|
-
altText: 'string', // (DEPRECATED) Initial value for the collect element.
|
|
1602
|
-
validations: [], // Optional. Array of validation rules.
|
|
1560
|
+
const collectElement = {
|
|
1561
|
+
type: Skyflow.ElementType.FILE_INPUT, // Skyflow.ElementType enum.
|
|
1562
|
+
table: 'string', // The table this data belongs to.
|
|
1563
|
+
column: 'string', // The column into which this data should be inserted.
|
|
1564
|
+
skyflowID: 'string', // The skyflow_id of the record.
|
|
1565
|
+
inputStyles: {}, // Optional, styles that should be applied to the form element.
|
|
1566
|
+
labelStyles: {}, // Optional, styles that will be applied to the label of the collect element.
|
|
1567
|
+
errorTextStyles:{}, // Optional, styles that will be applied to the errorText of the collect element.
|
|
1603
1568
|
}
|
|
1604
1569
|
```
|
|
1605
|
-
The `table` and `column` fields indicate which table and column
|
|
1606
|
-
|
|
1607
|
-
Note: Use dot-delimited strings to specify columns nested inside JSON fields (for example, `address.street.line1`).
|
|
1570
|
+
The `table` and `column` fields indicate which table and column the Element corresponds to.
|
|
1608
1571
|
|
|
1609
|
-
|
|
1572
|
+
`skyflowID` indicates the record that stores the file.
|
|
1610
1573
|
|
|
1611
|
-
|
|
1574
|
+
**Notes**:
|
|
1575
|
+
- `skyflowID` is required while creating File element
|
|
1576
|
+
- Use period-delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`).
|
|
1612
1577
|
|
|
1613
|
-
|
|
1614
|
-
* `complete`: applied when the Element has valid input
|
|
1615
|
-
* `empty`: applied when the Element has no input
|
|
1616
|
-
* `focus`: applied when the Element has focus
|
|
1617
|
-
* `invalid`: applied when the Element has invalid input
|
|
1618
|
-
* `cardIcon`: applied to the card type icon in CARD_NUMBER Element
|
|
1619
|
-
* `copyIcon`: applied to copy icon in Elements when enableCopy option is true
|
|
1620
|
-
* `global`: used for global styles like font-family.
|
|
1578
|
+
### Step 3: Mount elements to the DOM
|
|
1621
1579
|
|
|
1622
|
-
|
|
1580
|
+
To specify where to render Elements on your page, create placeholder `<div>` elements with unique `id` tags. For instance, the form below has an empty div with a unique id as a placeholder for a Skyflow Element.
|
|
1623
1581
|
|
|
1624
|
-
```
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
color: '#1d1d1d',
|
|
1631
|
-
fontFamily: '"Roboto", sans-serif'
|
|
1632
|
-
},
|
|
1633
|
-
complete: {
|
|
1634
|
-
color: '#4caf50',
|
|
1635
|
-
},
|
|
1636
|
-
empty: {},
|
|
1637
|
-
focus: {},
|
|
1638
|
-
invalid: {
|
|
1639
|
-
color: '#f44336',
|
|
1640
|
-
},
|
|
1641
|
-
cardIcon: {
|
|
1642
|
-
position: 'absolute',
|
|
1643
|
-
left: '8px',
|
|
1644
|
-
bottom: 'calc(50% - 12px)',
|
|
1645
|
-
},
|
|
1646
|
-
copyIcon: {
|
|
1647
|
-
position: 'absolute',
|
|
1648
|
-
right: '8px',
|
|
1649
|
-
},
|
|
1650
|
-
global: {
|
|
1651
|
-
'@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
|
|
1652
|
-
}
|
|
1653
|
-
}
|
|
1582
|
+
```html
|
|
1583
|
+
<form>
|
|
1584
|
+
<div id="file"/>
|
|
1585
|
+
<br/>
|
|
1586
|
+
<button type="submit">Submit</button>
|
|
1587
|
+
</form>
|
|
1654
1588
|
```
|
|
1655
|
-
The states that are available for `labelStyles` are `base`, `focus`, `global`.
|
|
1656
|
-
* requiredAsterisk: styles applied for the Asterisk symbol in the label.
|
|
1657
1589
|
|
|
1658
|
-
|
|
1590
|
+
Now, when the `mount(domElement)` method of the Element is called, the Element is inserted in the specified div. For instance, the call below inserts the Element into the div with the id "#file".
|
|
1659
1591
|
|
|
1660
1592
|
```javascript
|
|
1661
|
-
|
|
1662
|
-
base: {
|
|
1663
|
-
fontSize: '12px',
|
|
1664
|
-
fontWeight: 'bold',
|
|
1665
|
-
fontFamily: '"Roboto", sans-serif'
|
|
1666
|
-
},
|
|
1667
|
-
focus: {
|
|
1668
|
-
color: '#1d1d1d'
|
|
1669
|
-
},
|
|
1670
|
-
global: {
|
|
1671
|
-
'@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1593
|
+
element.mount('#file');
|
|
1674
1594
|
```
|
|
1675
|
-
|
|
1676
|
-
The JS SDK supports the following composable elements:
|
|
1677
|
-
|
|
1678
|
-
- `CARDHOLDER_NAME`
|
|
1679
|
-
- `CARD_NUMBER`
|
|
1680
|
-
- `EXPIRATION_DATE`
|
|
1681
|
-
- `EXPIRATION_MONTH`
|
|
1682
|
-
- `EXPIRATION_YEAR`
|
|
1683
|
-
- `CVV`
|
|
1684
|
-
- `INPUT_FIELD`
|
|
1685
|
-
- `PIN`
|
|
1686
|
-
|
|
1687
|
-
`Note`: Only when the entered value in the below composable elements is valid, the focus shifts automatically. The element types are:
|
|
1688
|
-
- `CARD_NUMBER`
|
|
1689
|
-
- `EXPIRATION_DATE`
|
|
1690
|
-
- `EXPIRATION_MONTH`
|
|
1691
|
-
- `EXPIRATION_YEAR`
|
|
1692
|
-
|
|
1693
|
-
The `INPUT_FIELD` type is a custom UI element without any built-in validations. For information on validations, see [validations](#validations).
|
|
1694
|
-
|
|
1695
|
-
Along with the Composable Element definition, you can define additional options for the element:
|
|
1595
|
+
Use the `unmount` method to reset a Collect Element to its initial state.
|
|
1696
1596
|
|
|
1697
1597
|
```javascript
|
|
1698
|
-
|
|
1699
|
-
required: false, // Optional, indicates whether the field is marked as required. Defaults to 'false'
|
|
1700
|
-
enableCardIcon: true, // Optional, indicates whether card icon should be enabled (only applicable for CARD_NUMBER ElementType)
|
|
1701
|
-
format: String, // Optional, format for the element (only applicable currently for EXPIRATION_DATE ElementType),
|
|
1702
|
-
enableCopy: false // Optional, enables the copy icon in collect and reveal elements to copy text to clipboard. Defaults to 'false')
|
|
1703
|
-
}
|
|
1598
|
+
element.unmount();
|
|
1704
1599
|
```
|
|
1600
|
+
### Step 4: Collect data from elements
|
|
1705
1601
|
|
|
1706
|
-
|
|
1707
|
-
- `enableCardIcon`: Whether or not the icon is visible for the CARD_NUMBER element. Defaults to `true`.
|
|
1708
|
-
- `format`: Format pattern for the element. Only applicable to EXPIRATION_DATE and EXPIRATION_YEAR element types.
|
|
1709
|
-
- `enableCopy`: Whether or not the copy icon is visible in collect and reveal elements. Defaults to `false`.
|
|
1602
|
+
When you're ready to upload the file, call the `uploadFiles()` method on the container object.
|
|
1710
1603
|
|
|
1711
|
-
|
|
1604
|
+
```javascript
|
|
1605
|
+
container.uploadFiles();
|
|
1606
|
+
```
|
|
1607
|
+
### File upload limitations:
|
|
1712
1608
|
|
|
1713
|
-
-
|
|
1714
|
-
-
|
|
1715
|
-
-
|
|
1716
|
-
-
|
|
1609
|
+
- Only non-executable file are allowed to be uploaded.
|
|
1610
|
+
- Files must have a maximum size of 32 MB
|
|
1611
|
+
- File columns can't enable tokenization, redaction, or arrays.
|
|
1612
|
+
- Re-uploading a file overwrites previously uploaded data.
|
|
1613
|
+
- Partial uploads or resuming a previous upload isn't supported.
|
|
1717
1614
|
|
|
1615
|
+
### End-to-end file upload
|
|
1718
1616
|
|
|
1719
|
-
|
|
1617
|
+
```javascript
|
|
1618
|
+
// Step 1.
|
|
1619
|
+
const container = skyflowClient.container(Skyflow.ContainerType.COLLECT);
|
|
1720
1620
|
|
|
1721
|
-
|
|
1722
|
-
|
|
1621
|
+
// Step 2.
|
|
1622
|
+
const element = container.create({
|
|
1623
|
+
table: 'pii_fields',
|
|
1624
|
+
column: 'file',
|
|
1625
|
+
skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
|
|
1626
|
+
inputstyles: {
|
|
1627
|
+
base: {
|
|
1628
|
+
color: '#1d1d1d',
|
|
1629
|
+
},
|
|
1630
|
+
},
|
|
1631
|
+
labelStyles: {
|
|
1632
|
+
base: {
|
|
1633
|
+
fontSize: '12px',
|
|
1634
|
+
fontWeight: 'bold',
|
|
1635
|
+
},
|
|
1636
|
+
},
|
|
1637
|
+
errorTextStyles: {
|
|
1638
|
+
base: {
|
|
1639
|
+
color: '#f44336',
|
|
1640
|
+
},
|
|
1641
|
+
},
|
|
1642
|
+
type: Skyflow.ElementType.FILE_INPUT,
|
|
1643
|
+
});
|
|
1723
1644
|
|
|
1645
|
+
// Step 3.
|
|
1646
|
+
element.mount('#file'); // Assumes there is a div with id='#file' in the webpage.
|
|
1724
1647
|
|
|
1725
|
-
|
|
1648
|
+
// Step 4.
|
|
1649
|
+
container.uploadFiles();
|
|
1650
|
+
```
|
|
1726
1651
|
|
|
1652
|
+
**Sample Response :**
|
|
1727
1653
|
```javascript
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the collect element.
|
|
1735
|
-
label: 'string', // Optional, label for the form element.
|
|
1736
|
-
placeholder: 'string', // Optional, placeholder for the form element.
|
|
1737
|
-
altText: 'string', // (DEPRECATED) string that acts as an initial value for the collect element.
|
|
1738
|
-
validations: [], // Optional, array of validation rules.
|
|
1654
|
+
{
|
|
1655
|
+
fileUploadResponse: [
|
|
1656
|
+
{
|
|
1657
|
+
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
|
|
1658
|
+
}
|
|
1659
|
+
]
|
|
1739
1660
|
}
|
|
1661
|
+
```
|
|
1662
|
+
### File upload with options:
|
|
1740
1663
|
|
|
1664
|
+
Along with fileElementInput, you can define other options in the Options object as described below:
|
|
1665
|
+
```js
|
|
1741
1666
|
const options = {
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
format: String, // Optional, format for the element (only applicable currently for EXPIRATION_DATE ElementType).
|
|
1745
|
-
enableCopy: false, // Optional, enables the copy icon in collect and reveal elements to copy text to clipboard. Defaults to 'false').
|
|
1746
|
-
};
|
|
1747
|
-
|
|
1748
|
-
const element = container.create(composableElement, options);
|
|
1667
|
+
allowedFileType: String[], // Optional, indicates the allowed file types for upload
|
|
1668
|
+
}
|
|
1749
1669
|
```
|
|
1670
|
+
`allowedFileType`: An array of string value that indicates the allowedFileTypes to be uploaded.
|
|
1750
1671
|
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
To specify where the Elements are rendered on your page, create a placeholder `<div>` element with unique `id` attribute. Use this empty `<div>` placeholder to mount the composable container.
|
|
1672
|
+
#### File upload with options example
|
|
1755
1673
|
|
|
1756
1674
|
```javascript
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
<br/>
|
|
1760
|
-
<div id="button-id"/>
|
|
1761
|
-
<button type="submit">Submit</button>
|
|
1762
|
-
</form>
|
|
1763
|
-
```
|
|
1764
|
-
Use the composable container's `mount(domElement)` method to insert the container's Elements into the specified `<div>`. For instance, the following call inserts Elements into the `<div>` with the `id "#composableContainer"`.
|
|
1765
|
-
|
|
1766
|
-
```javacript
|
|
1767
|
-
container.mount('#composableContainer');
|
|
1768
|
-
```
|
|
1675
|
+
// Create collect Container.
|
|
1676
|
+
const collectContainer = skyflowClient.container(Skyflow.ContainerType.COLLECT);
|
|
1769
1677
|
|
|
1770
|
-
|
|
1678
|
+
// Create collect elements.
|
|
1679
|
+
const cardNumberElement = collectContainer.create({
|
|
1680
|
+
table: 'newTable',
|
|
1681
|
+
column: 'card_number',
|
|
1682
|
+
inputstyles: {
|
|
1683
|
+
base: {
|
|
1684
|
+
color: '#1d1d1d',
|
|
1685
|
+
},
|
|
1686
|
+
},
|
|
1687
|
+
labelStyles: {
|
|
1688
|
+
base: {
|
|
1689
|
+
fontSize: '12px',
|
|
1690
|
+
fontWeight: 'bold',
|
|
1691
|
+
},
|
|
1692
|
+
},
|
|
1693
|
+
errorTextStyles: {
|
|
1694
|
+
base: {
|
|
1695
|
+
color: '#f44336',
|
|
1696
|
+
},
|
|
1697
|
+
},
|
|
1698
|
+
placeholder: 'card number',
|
|
1699
|
+
label: 'Card Number',
|
|
1700
|
+
type: Skyflow.ElementType.CARD_NUMBER,
|
|
1701
|
+
});
|
|
1702
|
+
const options = {
|
|
1703
|
+
allowedFileType: [".pdf",".png"];
|
|
1704
|
+
};
|
|
1705
|
+
const fileElement = collectContainer.create({
|
|
1706
|
+
table: 'newTable',
|
|
1707
|
+
column: 'file',
|
|
1708
|
+
skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
|
|
1709
|
+
inputstyles: {
|
|
1710
|
+
base: {
|
|
1711
|
+
color: '#1d1d1d',
|
|
1712
|
+
},
|
|
1713
|
+
},
|
|
1714
|
+
labelStyles: {
|
|
1715
|
+
base: {
|
|
1716
|
+
fontSize: '12px',
|
|
1717
|
+
fontWeight: 'bold',
|
|
1718
|
+
},
|
|
1719
|
+
},
|
|
1720
|
+
errorTextStyles: {
|
|
1721
|
+
base: {
|
|
1722
|
+
color: '#f44336',
|
|
1723
|
+
},
|
|
1724
|
+
},
|
|
1725
|
+
type: Skyflow.ElementType.FILE_INPUT,
|
|
1726
|
+
},
|
|
1727
|
+
options
|
|
1728
|
+
);
|
|
1771
1729
|
|
|
1730
|
+
// Mount the elements.
|
|
1731
|
+
cardNumberElement.mount('#collectCardNumber');
|
|
1732
|
+
fileElement.mount('#collectFile');
|
|
1772
1733
|
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
- `upsert`: To support upsert operations, the table containing the data and a column marked as unique in that table.
|
|
1734
|
+
// Collect and upload methods.
|
|
1735
|
+
collectContainer.collect({});
|
|
1736
|
+
collectContainer.uploadFiles();
|
|
1777
1737
|
|
|
1738
|
+
```
|
|
1739
|
+
**Sample Response for collect():**
|
|
1778
1740
|
```javascript
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
additionalFields: {
|
|
1782
|
-
records: [
|
|
1783
|
-
{
|
|
1784
|
-
table: 'string', // Table into which record should be inserted.
|
|
1785
|
-
fields: {
|
|
1786
|
-
column1: 'value', // Column names should match vault column names.
|
|
1787
|
-
// ...additional fields here.
|
|
1788
|
-
},
|
|
1789
|
-
},
|
|
1790
|
-
// ...additional records here.
|
|
1791
|
-
],
|
|
1792
|
-
}, // Optional
|
|
1793
|
-
upsert: [ // Upsert operations support in the vault
|
|
1741
|
+
{
|
|
1742
|
+
"records": [
|
|
1794
1743
|
{
|
|
1795
|
-
table:
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
}
|
|
1744
|
+
"table": "newTable",
|
|
1745
|
+
"fields": {
|
|
1746
|
+
"card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
]
|
|
1750
|
+
}
|
|
1800
1751
|
```
|
|
1801
|
-
|
|
1802
|
-
|
|
1752
|
+
**Sample Response for file uploadFiles() :**
|
|
1753
|
+
```javascript
|
|
1754
|
+
{
|
|
1755
|
+
"fileUploadResponse": [
|
|
1756
|
+
{
|
|
1757
|
+
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
|
|
1758
|
+
}
|
|
1759
|
+
]
|
|
1760
|
+
}
|
|
1761
|
+
```
|
|
1762
|
+
#### File upload with additional elements
|
|
1803
1763
|
|
|
1804
1764
|
```javascript
|
|
1805
|
-
//
|
|
1806
|
-
const
|
|
1807
|
-
|
|
1808
|
-
|
|
1765
|
+
// Create collect Container.
|
|
1766
|
+
const collectContainer = skyflowClient.container(Skyflow.ContainerType.COLLECT);
|
|
1767
|
+
|
|
1768
|
+
// Create collect elements.
|
|
1769
|
+
const cardNumberElement = collectContainer.create({
|
|
1770
|
+
table: 'newTable',
|
|
1771
|
+
column: 'card_number',
|
|
1772
|
+
inputstyles: {
|
|
1809
1773
|
base: {
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1774
|
+
color: '#1d1d1d',
|
|
1775
|
+
},
|
|
1776
|
+
},
|
|
1777
|
+
labelStyles: {
|
|
1778
|
+
base: {
|
|
1779
|
+
fontSize: '12px',
|
|
1780
|
+
fontWeight: 'bold',
|
|
1814
1781
|
},
|
|
1815
1782
|
},
|
|
1816
1783
|
errorTextStyles: {
|
|
1817
1784
|
base: {
|
|
1818
|
-
color: '
|
|
1785
|
+
color: '#f44336',
|
|
1819
1786
|
},
|
|
1820
1787
|
},
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
containerOptions
|
|
1826
|
-
);
|
|
1827
|
-
|
|
1828
|
-
// Step 2
|
|
1788
|
+
placeholder: 'card number',
|
|
1789
|
+
label: 'Card Number',
|
|
1790
|
+
type: Skyflow.ElementType.CARD_NUMBER,
|
|
1791
|
+
});
|
|
1829
1792
|
|
|
1830
|
-
const
|
|
1831
|
-
|
|
1793
|
+
const fileElement = collectContainer.create({
|
|
1794
|
+
table: 'newTable',
|
|
1795
|
+
column: 'file',
|
|
1796
|
+
skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
|
|
1797
|
+
inputstyles: {
|
|
1832
1798
|
base: {
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1799
|
+
color: '#1d1d1d',
|
|
1800
|
+
},
|
|
1801
|
+
},
|
|
1802
|
+
labelStyles: {
|
|
1803
|
+
base: {
|
|
1804
|
+
fontSize: '12px',
|
|
1805
|
+
fontWeight: 'bold',
|
|
1839
1806
|
},
|
|
1840
1807
|
},
|
|
1841
|
-
labelStyles: {},
|
|
1842
1808
|
errorTextStyles: {
|
|
1843
|
-
base: {
|
|
1809
|
+
base: {
|
|
1810
|
+
color: '#f44336',
|
|
1811
|
+
},
|
|
1844
1812
|
},
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
const cardHolderNameElement = composableContainer.create({
|
|
1848
|
-
table: 'pii_fields',
|
|
1849
|
-
column: 'first_name',
|
|
1850
|
-
...collectStylesOptions,
|
|
1851
|
-
placeholder: 'Cardholder Name',
|
|
1852
|
-
type: Skyflow.ElementType.CARDHOLDER_NAME,
|
|
1853
|
-
});
|
|
1854
|
-
|
|
1855
|
-
const cardNumberElement = composableContainer.create({
|
|
1856
|
-
table: 'pii_fields',
|
|
1857
|
-
column: 'card_number',
|
|
1858
|
-
...collectStylesOptions,
|
|
1859
|
-
placeholder: 'Card Number',
|
|
1860
|
-
type: Skyflow.ElementType.CARD_NUMBER,
|
|
1813
|
+
type: Skyflow.ElementType.FILE_INPUT,
|
|
1861
1814
|
});
|
|
1862
1815
|
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
...collectStylesOptions,
|
|
1867
|
-
placeholder: 'CVV',
|
|
1868
|
-
type: Skyflow.ElementType.CVV,
|
|
1869
|
-
});
|
|
1816
|
+
// Mount the elements.
|
|
1817
|
+
cardNumberElement.mount('#collectCardNumber');
|
|
1818
|
+
fileElement.mount('#collectFile');
|
|
1870
1819
|
|
|
1871
|
-
//
|
|
1872
|
-
|
|
1820
|
+
// Collect and upload methods.
|
|
1821
|
+
collectContainer.collect({});
|
|
1822
|
+
collectContainer.uploadFiles();
|
|
1873
1823
|
|
|
1874
|
-
// Step 4
|
|
1875
|
-
composableContainer.collect({
|
|
1876
|
-
tokens: true,
|
|
1877
|
-
});
|
|
1878
1824
|
```
|
|
1879
|
-
|
|
1880
|
-
|
|
1825
|
+
**Sample Response for collect():**
|
|
1881
1826
|
```javascript
|
|
1882
1827
|
{
|
|
1883
|
-
|
|
1828
|
+
"records": [
|
|
1829
|
+
{
|
|
1830
|
+
"table": "newTable",
|
|
1831
|
+
"fields": {
|
|
1832
|
+
"card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
]
|
|
1836
|
+
}
|
|
1837
|
+
```
|
|
1838
|
+
**Sample Response for file uploadFiles() :**
|
|
1839
|
+
```javascript
|
|
1840
|
+
{
|
|
1841
|
+
"fileUploadResponse": [
|
|
1884
1842
|
{
|
|
1885
|
-
"
|
|
1886
|
-
"fields": {
|
|
1887
|
-
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882",
|
|
1888
|
-
"first_name": "63b5eeee-3624-493f-825e-137a9336f882",
|
|
1889
|
-
"card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
|
|
1890
|
-
"cvv": "7baf5bda-aa22-4587-a5c5-412f6f783a19",
|
|
1891
|
-
}
|
|
1843
|
+
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
|
|
1892
1844
|
}
|
|
1893
1845
|
]
|
|
1894
1846
|
}
|
|
1895
1847
|
```
|
|
1896
|
-
For information on validations, see [validations](#validations).
|
|
1897
1848
|
|
|
1898
|
-
|
|
1849
|
+
Note: File name should contain only alphanumeric characters and !-_.*()
|
|
1899
1850
|
|
|
1900
|
-
|
|
1851
|
+
# Securely collecting data client-side using Composable Elements
|
|
1852
|
+
- [**Using Skyflow Composable Elements to collect data**](#using-skyflow-composable-elements-to-collect-data)
|
|
1853
|
+
- [**Event listener on Composable Element**](#set-an-event-listener-on-composable-elements)
|
|
1854
|
+
- [**Event listener on Composable Container**](#set-an-event-listener-on-a-composable-container)
|
|
1855
|
+
- [**Update Composable Elements**](#update-composable-elements)
|
|
1856
|
+
- [**Using Skyflow File Element to upload a file**](#using-skyflow-composable-file-element-to-upload-a-file)
|
|
1857
|
+
- [**Using Skyflow File Element to upload multiple files**](#using-skyflow-composable-file-element-to-upload-multiple-files)
|
|
1901
1858
|
|
|
1902
|
-
```javascript
|
|
1903
|
-
element.on(Skyflow.EventName,handler:function)
|
|
1904
|
-
```
|
|
1905
1859
|
|
|
1860
|
+
## Using Skyflow Composable Elements to collect data
|
|
1861
|
+
Composable Elements combine multiple Skyflow Elements in a single iframe, letting you create multiple Skyflow Elements in a single row. The following steps create a composable element and securely collect data through it.
|
|
1906
1862
|
|
|
1907
|
-
|
|
1863
|
+
### Step 1: Create a composable container
|
|
1908
1864
|
|
|
1909
|
-
|
|
1910
|
-
- `READY`: Triggered when the Element is fully rendered.
|
|
1911
|
-
- `FOCUS`: Triggered when the Element gains focus.
|
|
1912
|
-
- `BLUR`: Triggered when the Element loses focus.
|
|
1865
|
+
Create a container for the composable element using the `container(Skyflow.ContainerType)` method of the Skyflow client:
|
|
1913
1866
|
|
|
1914
|
-
|
|
1867
|
+
``` javascript
|
|
1868
|
+
const collectContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE,containerOptions);
|
|
1869
|
+
```
|
|
1870
|
+
Pass an options object that contains the following keys:
|
|
1871
|
+
|
|
1872
|
+
1. `layout`: An array that indicates the number of rows in the container and the number of elements in each row. The index value of the array defines the number of rows, and each value in the array represents the number of elements in that row, in order.
|
|
1873
|
+
|
|
1874
|
+
For example: `[2,1]` means the container has two rows, with two elements in the first row and one element in the second row.
|
|
1875
|
+
|
|
1876
|
+
`Note`: The sum of values in the layout array should be equal to the number of elements created
|
|
1877
|
+
|
|
1878
|
+
2. `styles`: CSS styles to apply to the composable container.
|
|
1879
|
+
3. `errorTextStyles`: CSS styles to apply if an error is encountered.
|
|
1915
1880
|
|
|
1916
1881
|
```javascript
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1882
|
+
const options = {
|
|
1883
|
+
layout: [2, 1], // Required
|
|
1884
|
+
styles: { // Optional
|
|
1885
|
+
base: {
|
|
1886
|
+
border: '1px solid #DFE3EB',
|
|
1887
|
+
padding: '8px',
|
|
1888
|
+
borderRadius: '4px',
|
|
1889
|
+
margin: '12px 2px',
|
|
1890
|
+
},
|
|
1891
|
+
},
|
|
1892
|
+
errorTextStyles: { // Optional
|
|
1893
|
+
base: {
|
|
1894
|
+
color: 'red',
|
|
1895
|
+
fontFamily: '"Roboto", sans-serif'
|
|
1896
|
+
},
|
|
1897
|
+
global: {
|
|
1898
|
+
'@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
|
|
1899
|
+
}
|
|
1900
|
+
},
|
|
1901
|
+
};
|
|
1924
1902
|
```
|
|
1925
|
-
`Note`: Events only include element values when in the state object when env is DEV. By default, value is an empty string.
|
|
1926
1903
|
|
|
1927
|
-
###
|
|
1904
|
+
### Step 2: Create Composable Elements
|
|
1905
|
+
Composable Elements use the following schema:
|
|
1928
1906
|
|
|
1929
1907
|
```javascript
|
|
1930
|
-
const
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
base: {
|
|
1942
|
-
color: 'red'
|
|
1943
|
-
}
|
|
1944
|
-
}
|
|
1908
|
+
const composableElement = {
|
|
1909
|
+
table: 'string', // Required. The table this data belongs to.
|
|
1910
|
+
column: 'string', // Required. The column this data belongs to.
|
|
1911
|
+
type: Skyflow.ElementType, // Skyflow.ElementType enum.
|
|
1912
|
+
inputStyles: {}, // Optional. Styles applied to the form element.
|
|
1913
|
+
labelStyles: {}, // Optional. Styles for the label of the collect element.
|
|
1914
|
+
errorTextStyles: {}, // Optional. Styles for the errorText of the collect element.
|
|
1915
|
+
label: 'string', // Optional. Label for the form element.
|
|
1916
|
+
placeholder: 'string', // Optional. Placeholder for the form element.
|
|
1917
|
+
altText: 'string', // (DEPRECATED) Initial value for the collect element.
|
|
1918
|
+
validations: [], // Optional. Array of validation rules.
|
|
1945
1919
|
}
|
|
1920
|
+
```
|
|
1921
|
+
The `table` and `column` fields indicate which table and column in the vault the Element correspond to.
|
|
1946
1922
|
|
|
1947
|
-
|
|
1923
|
+
Note: Use dot-delimited strings to specify columns nested inside JSON fields (for example, `address.street.line1`).
|
|
1948
1924
|
|
|
1949
|
-
|
|
1950
|
-
table: 'pii_fields',
|
|
1951
|
-
column: 'primary_card.cvv',
|
|
1952
|
-
type: Skyflow.ElementType.CVV,
|
|
1953
|
-
});
|
|
1925
|
+
All elements can be styled with [JSS](https://cssinjs.org/?v=v10.7.1) syntax.
|
|
1954
1926
|
|
|
1955
|
-
|
|
1927
|
+
The `inputStyles` field accepts an object of CSS properties to apply to the form element in the following states:
|
|
1956
1928
|
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1929
|
+
* `base`: all variants inherit from these styles
|
|
1930
|
+
* `complete`: applied when the Element has valid input
|
|
1931
|
+
* `empty`: applied when the Element has no input
|
|
1932
|
+
* `focus`: applied when the Element has focus
|
|
1933
|
+
* `invalid`: applied when the Element has invalid input
|
|
1934
|
+
* `cardIcon`: applied to the card type icon in CARD_NUMBER Element
|
|
1935
|
+
* `copyIcon`: applied to copy icon in Elements when enableCopy option is true
|
|
1936
|
+
* `global`: used for global styles like font-family.
|
|
1963
1937
|
|
|
1964
|
-
|
|
1938
|
+
An example of an `inputStyles` object:
|
|
1965
1939
|
|
|
1966
1940
|
```javascript
|
|
1967
|
-
{
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1941
|
+
inputStyles: {
|
|
1942
|
+
base: {
|
|
1943
|
+
border: '1px solid #eae8ee',
|
|
1944
|
+
padding: '10px 16px',
|
|
1945
|
+
borderRadius: '4px',
|
|
1946
|
+
color: '#1d1d1d',
|
|
1947
|
+
fontFamily: '"Roboto", sans-serif'
|
|
1948
|
+
},
|
|
1949
|
+
complete: {
|
|
1950
|
+
color: '#4caf50',
|
|
1951
|
+
},
|
|
1952
|
+
empty: {},
|
|
1953
|
+
focus: {},
|
|
1954
|
+
invalid: {
|
|
1955
|
+
color: '#f44336',
|
|
1956
|
+
},
|
|
1957
|
+
cardIcon: {
|
|
1958
|
+
position: 'absolute',
|
|
1959
|
+
left: '8px',
|
|
1960
|
+
bottom: 'calc(50% - 12px)',
|
|
1961
|
+
},
|
|
1962
|
+
copyIcon: {
|
|
1963
|
+
position: 'absolute',
|
|
1964
|
+
right: '8px',
|
|
1965
|
+
},
|
|
1966
|
+
global: {
|
|
1967
|
+
'@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
|
|
1968
|
+
}
|
|
1973
1969
|
}
|
|
1974
1970
|
```
|
|
1971
|
+
The states that are available for `labelStyles` are `base`, `focus`, `global`.
|
|
1972
|
+
* requiredAsterisk: styles applied for the Asterisk symbol in the label.
|
|
1975
1973
|
|
|
1976
|
-
|
|
1974
|
+
An example `labelStyles` object:
|
|
1977
1975
|
|
|
1978
1976
|
```javascript
|
|
1979
|
-
{
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1977
|
+
labelStyles: {
|
|
1978
|
+
base: {
|
|
1979
|
+
fontSize: '12px',
|
|
1980
|
+
fontWeight: 'bold',
|
|
1981
|
+
fontFamily: '"Roboto", sans-serif'
|
|
1982
|
+
},
|
|
1983
|
+
focus: {
|
|
1984
|
+
color: '#1d1d1d'
|
|
1985
|
+
},
|
|
1986
|
+
global: {
|
|
1987
|
+
'@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
|
|
1988
|
+
}
|
|
1985
1989
|
}
|
|
1986
1990
|
```
|
|
1987
1991
|
|
|
1988
|
-
|
|
1989
|
-
You can update composable element properties with the `update` interface.
|
|
1990
|
-
|
|
1992
|
+
The JS SDK supports the following composable elements:
|
|
1991
1993
|
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
label: 'string', // Optional. Label for the form element.
|
|
2001
|
-
placeholder: 'string', // Optional. Placeholder for the form element.
|
|
2002
|
-
validations: [], // Optional. Array of validation rules.
|
|
2003
|
-
};
|
|
2004
|
-
```
|
|
1994
|
+
- `CARDHOLDER_NAME`
|
|
1995
|
+
- `CARD_NUMBER`
|
|
1996
|
+
- `EXPIRATION_DATE`
|
|
1997
|
+
- `EXPIRATION_MONTH`
|
|
1998
|
+
- `EXPIRATION_YEAR`
|
|
1999
|
+
- `CVV`
|
|
2000
|
+
- `INPUT_FIELD`
|
|
2001
|
+
- `PIN`
|
|
2005
2002
|
|
|
2006
|
-
Only
|
|
2003
|
+
`Note`: Only when the entered value in the below composable elements is valid, the focus shifts automatically. The element types are:
|
|
2004
|
+
- `CARD_NUMBER`
|
|
2005
|
+
- `EXPIRATION_DATE`
|
|
2006
|
+
- `EXPIRATION_MONTH`
|
|
2007
|
+
- `EXPIRATION_YEAR`
|
|
2007
2008
|
|
|
2008
|
-
|
|
2009
|
+
The `INPUT_FIELD` type is a custom UI element without any built-in validations. For information on validations, see [validations](#validations).
|
|
2009
2010
|
|
|
2010
|
-
|
|
2011
|
+
Along with the Composable Element definition, you can define additional options for the element:
|
|
2011
2012
|
|
|
2012
|
-
### End to end example
|
|
2013
2013
|
```javascript
|
|
2014
|
-
const
|
|
2014
|
+
const options = {
|
|
2015
|
+
required: false, // Optional, indicates whether the field is marked as required. Defaults to 'false'
|
|
2016
|
+
enableCardIcon: true, // Optional, indicates whether card icon should be enabled (only applicable for CARD_NUMBER ElementType)
|
|
2017
|
+
format: String, // Optional, format for the element (only applicable currently for EXPIRATION_DATE ElementType),
|
|
2018
|
+
enableCopy: false // Optional, enables the copy icon in collect and reveal elements to copy text to clipboard. Defaults to 'false')
|
|
2019
|
+
}
|
|
2020
|
+
```
|
|
2015
2021
|
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
);
|
|
2022
|
+
- `required`: Whether or not the field is marked as required. Defaults to `false`.
|
|
2023
|
+
- `enableCardIcon`: Whether or not the icon is visible for the CARD_NUMBER element. Defaults to `true`.
|
|
2024
|
+
- `format`: Format pattern for the element. Only applicable to EXPIRATION_DATE and EXPIRATION_YEAR element types.
|
|
2025
|
+
- `enableCopy`: Whether or not the copy icon is visible in collect and reveal elements. Defaults to `false`.
|
|
2021
2026
|
|
|
2022
|
-
|
|
2023
|
-
inputStyles: {
|
|
2024
|
-
base: {
|
|
2025
|
-
fontFamily: 'Inter',
|
|
2026
|
-
fontStyle: 'normal',
|
|
2027
|
-
fontWeight: 400,
|
|
2028
|
-
fontSize: '14px',
|
|
2029
|
-
lineHeight: '21px',
|
|
2030
|
-
width: '294px',
|
|
2031
|
-
},
|
|
2032
|
-
},
|
|
2033
|
-
labelStyles: {},
|
|
2034
|
-
errorTextStyles: {
|
|
2035
|
-
base: {},
|
|
2036
|
-
},
|
|
2037
|
-
};
|
|
2027
|
+
The accepted `EXPIRATION_DATE` values are
|
|
2038
2028
|
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
...stylesOptions,
|
|
2044
|
-
placeholder: 'Cardholder Name',
|
|
2045
|
-
type: Skyflow.ElementType.CARDHOLDER_NAME,
|
|
2046
|
-
});
|
|
2029
|
+
- `MM/YY` (default)
|
|
2030
|
+
- `MM/YYYY`
|
|
2031
|
+
- `YY/MM`
|
|
2032
|
+
- `YYYY/MM`
|
|
2047
2033
|
|
|
2048
2034
|
|
|
2049
|
-
|
|
2050
|
-
table: 'pii_fields',
|
|
2051
|
-
column: 'card_number',
|
|
2052
|
-
...stylesOptions,
|
|
2053
|
-
placeholder: 'Card Number',
|
|
2054
|
-
type: Skyflow.ElementType.CARD_NUMBER,
|
|
2055
|
-
});
|
|
2035
|
+
The accepted `EXPIRATION_YEAR` values are
|
|
2056
2036
|
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
column: 'cvv',
|
|
2060
|
-
...stylesOptions,
|
|
2061
|
-
placeholder: 'CVV',
|
|
2062
|
-
type: Skyflow.ElementType.CVV,
|
|
2063
|
-
});
|
|
2037
|
+
- `YY` (default)
|
|
2038
|
+
- `YYYY`
|
|
2064
2039
|
|
|
2065
|
-
// Mount the composable container.
|
|
2066
|
-
composableContainer.mount('#compostableContainer'); // Assumes there is a div with id='#composableContainer' in the webpage.
|
|
2067
|
-
|
|
2068
|
-
// ...
|
|
2069
|
-
|
|
2070
|
-
// Update validations property on cvvElement.
|
|
2071
|
-
cvvElement.update({
|
|
2072
|
-
validations: [{
|
|
2073
|
-
type: Skyflow.ValidationRuleType.LENGTH_MATCH_RULE,
|
|
2074
|
-
params: {
|
|
2075
|
-
max: 3,
|
|
2076
|
-
error: 'cvv must be 3 digits',
|
|
2077
|
-
},
|
|
2078
|
-
}]
|
|
2079
|
-
})
|
|
2080
2040
|
|
|
2081
|
-
|
|
2082
|
-
cardHolderNameElement.update({
|
|
2083
|
-
label: 'CARDHOLDER NAME',
|
|
2084
|
-
placeholder: 'Eg: John'
|
|
2085
|
-
});
|
|
2041
|
+
Once you define the Element object and options, add it to the container using the `create(element, options)` method:
|
|
2086
2042
|
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
table:'
|
|
2090
|
-
column:'
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2043
|
+
```javascript
|
|
2044
|
+
const composableElement = {
|
|
2045
|
+
table: 'string', // Required, the table this data belongs to.
|
|
2046
|
+
column: 'string', // Required, the column into which this data should be inserted.
|
|
2047
|
+
type: Skyflow.ElementType, // Skyflow.ElementType enum.
|
|
2048
|
+
inputStyles: {}, // Optional, styles that should be applied to the form element.
|
|
2049
|
+
labelStyles: {}, // Optional, styles that will be applied to the label of the collect element.
|
|
2050
|
+
errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the collect element.
|
|
2051
|
+
label: 'string', // Optional, label for the form element.
|
|
2052
|
+
placeholder: 'string', // Optional, placeholder for the form element.
|
|
2053
|
+
altText: 'string', // (DEPRECATED) string that acts as an initial value for the collect element.
|
|
2054
|
+
validations: [], // Optional, array of validation rules.
|
|
2055
|
+
}
|
|
2097
2056
|
|
|
2057
|
+
const options = {
|
|
2058
|
+
required: false, // Optional, indicates whether the field is marked as required. Defaults to 'false'.
|
|
2059
|
+
enableCardIcon: true, // Optional, indicates whether card icon should be enabled (only applicable for CARD_NUMBER ElementType).
|
|
2060
|
+
format: String, // Optional, format for the element (only applicable currently for EXPIRATION_DATE ElementType).
|
|
2061
|
+
enableCopy: false, // Optional, enables the copy icon in collect and reveal elements to copy text to clipboard. Defaults to 'false').
|
|
2062
|
+
};
|
|
2098
2063
|
|
|
2064
|
+
const element = container.create(composableElement, options);
|
|
2099
2065
|
```
|
|
2100
|
-
### Set an event listener on a composable container
|
|
2101
|
-
Currently, the SDK supports one event:
|
|
2102
|
-
- `SUBMIT`: Triggered when the `Enter` key is pressed in any container element.
|
|
2103
2066
|
|
|
2104
|
-
|
|
2067
|
+
### Step 3: Mount Container to the DOM
|
|
2068
|
+
To specify where the Elements are rendered on your page, create a placeholder `<div>` element with unique `id` attribute. Use this empty `<div>` placeholder to mount the composable container.
|
|
2105
2069
|
|
|
2106
|
-
### Example
|
|
2107
2070
|
```javascript
|
|
2108
|
-
|
|
2071
|
+
<form>
|
|
2072
|
+
<div id="composableContainer"/>
|
|
2073
|
+
<br/>
|
|
2074
|
+
<div id="button-id"/>
|
|
2075
|
+
<button type="submit">Submit</button>
|
|
2076
|
+
</form>
|
|
2077
|
+
```
|
|
2078
|
+
Use the composable container's `mount(domElement)` method to insert the container's Elements into the specified `<div>`. For instance, the following call inserts Elements into the `<div>` with the `id "#composableContainer"`.
|
|
2109
2079
|
|
|
2110
|
-
|
|
2111
|
-
|
|
2080
|
+
```javacript
|
|
2081
|
+
container.mount('#composableContainer');
|
|
2082
|
+
```
|
|
2112
2083
|
|
|
2113
|
-
|
|
2114
|
-
const cvv = composableContainer.create({
|
|
2115
|
-
table: 'pii_fields',
|
|
2116
|
-
column: 'primary_card.cvv',
|
|
2117
|
-
type: Skyflow.ElementType.CVV,
|
|
2118
|
-
});
|
|
2084
|
+
### Step 4: Collect data from elements
|
|
2119
2085
|
|
|
2120
|
-
// Mounting the container.
|
|
2121
|
-
composableContainer.mount('#cvvContainer');
|
|
2122
2086
|
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2087
|
+
When the form is ready to be submitted, call the container's `collect(options?)` method. The options parameter takes an object of optional parameters as follows:
|
|
2088
|
+
- `tokens`: Whether or not tokens for the collected data are returned. Defaults to 'true'
|
|
2089
|
+
- `additionalFields`: Non-PCI elements data to insert into the vault, specified in the records object format.
|
|
2090
|
+
- `upsert`: To support upsert operations, the table containing the data and a column marked as unique in that table.
|
|
2091
|
+
|
|
2092
|
+
```javascript
|
|
2093
|
+
const options = {
|
|
2094
|
+
tokens: true, // Optional, indicates whether tokens for the collected data should be returned. Defaults to 'true'.
|
|
2095
|
+
additionalFields: {
|
|
2096
|
+
records: [
|
|
2097
|
+
{
|
|
2098
|
+
table: 'string', // Table into which record should be inserted.
|
|
2099
|
+
fields: {
|
|
2100
|
+
column1: 'value', // Column names should match vault column names.
|
|
2101
|
+
// ...additional fields here.
|
|
2102
|
+
},
|
|
2103
|
+
},
|
|
2104
|
+
// ...additional records here.
|
|
2105
|
+
],
|
|
2106
|
+
}, // Optional
|
|
2107
|
+
upsert: [ // Upsert operations support in the vault
|
|
2108
|
+
{
|
|
2109
|
+
table: 'string', // Table name
|
|
2110
|
+
column: 'value', // Unique column in the table
|
|
2111
|
+
},
|
|
2112
|
+
], // Optional
|
|
2113
|
+
};
|
|
2128
2114
|
```
|
|
2129
2115
|
|
|
2130
|
-
|
|
2131
|
-
# Securely revealing data client-side
|
|
2132
|
-
- [**Retrieving data from the vault**](#retrieving-data-from-the-vault)
|
|
2133
|
-
- [**Using Skyflow Elements to reveal data**](#using-skyflow-elements-to-reveal-data)
|
|
2134
|
-
- [**UI Error for Reveal Elements**](#ui-error-for-reveal-elements)
|
|
2135
|
-
- [**Set token for Reveal Elements**](#set-token-for-reveal-elements)
|
|
2136
|
-
- [**Set and clear altText for Reveal Elements**](#set-and-clear-alttext-for-reveal-elements)
|
|
2137
|
-
- [**Render a file with a File Element**](#render-a-file-with-a-file-element)
|
|
2138
|
-
- [**Update Reveal Elements**](#update-reveal-elements)
|
|
2116
|
+
### End to end example of collecting data with Composable Elements
|
|
2139
2117
|
|
|
2140
|
-
|
|
2118
|
+
```javascript
|
|
2119
|
+
// Step 1
|
|
2120
|
+
const containerOptions = {
|
|
2121
|
+
layout: [2, 1],
|
|
2122
|
+
styles: {
|
|
2123
|
+
base: {
|
|
2124
|
+
border: '1px solid #eae8ee',
|
|
2125
|
+
padding: '10px 16px',
|
|
2126
|
+
borderRadius: '4px',
|
|
2127
|
+
margin: '12px 2px',
|
|
2128
|
+
},
|
|
2129
|
+
},
|
|
2130
|
+
errorTextStyles: {
|
|
2131
|
+
base: {
|
|
2132
|
+
color: 'red',
|
|
2133
|
+
},
|
|
2134
|
+
},
|
|
2135
|
+
};
|
|
2141
2136
|
|
|
2142
|
-
|
|
2137
|
+
const composableContainer = skyflowClient.container(
|
|
2138
|
+
Skyflow.ContainerType.COMPOSABLE,
|
|
2139
|
+
containerOptions
|
|
2140
|
+
);
|
|
2143
2141
|
|
|
2144
|
-
|
|
2145
|
-
In order to retrieve data from your vault using tokens that you have previously generated for that data, you can use the `detokenize(records)` method. The records parameter takes a JSON object that contains `records` to be fetched as shown below.
|
|
2142
|
+
// Step 2
|
|
2146
2143
|
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2144
|
+
const collectStylesOptions = {
|
|
2145
|
+
inputStyles: {
|
|
2146
|
+
base: {
|
|
2147
|
+
fontFamily: 'Inter',
|
|
2148
|
+
fontStyle: 'normal',
|
|
2149
|
+
fontWeight: 400,
|
|
2150
|
+
fontSize: '14px',
|
|
2151
|
+
lineHeight: '21px',
|
|
2152
|
+
width: '294px',
|
|
2153
2153
|
},
|
|
2154
|
-
|
|
2154
|
+
},
|
|
2155
|
+
labelStyles: {},
|
|
2156
|
+
errorTextStyles: {
|
|
2157
|
+
base: {},
|
|
2158
|
+
},
|
|
2155
2159
|
};
|
|
2156
2160
|
|
|
2157
|
-
|
|
2161
|
+
const cardHolderNameElement = composableContainer.create({
|
|
2162
|
+
table: 'pii_fields',
|
|
2163
|
+
column: 'first_name',
|
|
2164
|
+
...collectStylesOptions,
|
|
2165
|
+
placeholder: 'Cardholder Name',
|
|
2166
|
+
type: Skyflow.ElementType.CARDHOLDER_NAME,
|
|
2167
|
+
});
|
|
2158
2168
|
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2169
|
+
const cardNumberElement = composableContainer.create({
|
|
2170
|
+
table: 'pii_fields',
|
|
2171
|
+
column: 'card_number',
|
|
2172
|
+
...collectStylesOptions,
|
|
2173
|
+
placeholder: 'Card Number',
|
|
2174
|
+
type: Skyflow.ElementType.CARD_NUMBER,
|
|
2175
|
+
});
|
|
2162
2176
|
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2177
|
+
const cvvElement = composableContainer.create({
|
|
2178
|
+
table: 'pii_fields',
|
|
2179
|
+
column: 'cvv',
|
|
2180
|
+
...collectStylesOptions,
|
|
2181
|
+
placeholder: 'CVV',
|
|
2182
|
+
type: Skyflow.ElementType.CVV,
|
|
2183
|
+
});
|
|
2184
|
+
|
|
2185
|
+
// Step 3
|
|
2186
|
+
composableContainer.mount('#composableContainer'); // Assumes there is a div with id='#composableContainer' in the webpage.
|
|
2187
|
+
|
|
2188
|
+
// Step 4
|
|
2189
|
+
composableContainer.collect({
|
|
2190
|
+
tokens: true,
|
|
2174
2191
|
});
|
|
2175
2192
|
```
|
|
2193
|
+
### Sample Response:
|
|
2176
2194
|
|
|
2177
|
-
The sample response:
|
|
2178
2195
|
```javascript
|
|
2179
2196
|
{
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
]
|
|
2197
|
+
"records": [
|
|
2198
|
+
{
|
|
2199
|
+
"table": "pii_fields",
|
|
2200
|
+
"fields": {
|
|
2201
|
+
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882",
|
|
2202
|
+
"first_name": "63b5eeee-3624-493f-825e-137a9336f882",
|
|
2203
|
+
"card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
|
|
2204
|
+
"cvv": "7baf5bda-aa22-4587-a5c5-412f6f783a19",
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
]
|
|
2192
2208
|
}
|
|
2193
2209
|
```
|
|
2210
|
+
For information on validations, see [validations](#validations).
|
|
2194
2211
|
|
|
2195
|
-
|
|
2196
|
-
You can retrieve data from the vault with the `get(records, options)` method using either Skyflow IDs or unique column values.
|
|
2212
|
+
### Set an event listener on Composable Elements:
|
|
2197
2213
|
|
|
2198
|
-
|
|
2214
|
+
You can communicate with Skyflow Elements by listening to element events:
|
|
2199
2215
|
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2216
|
+
```javascript
|
|
2217
|
+
element.on(Skyflow.EventName,handler:function)
|
|
2218
|
+
```
|
|
2203
2219
|
|
|
2204
|
-
- You can use either Skyflow IDs or unique values to retrieve records. You can't use both at the same time.
|
|
2205
|
-
- `options` parameter is applicable only for retrieving tokens using Skyflow ID.
|
|
2206
|
-
- You can't pass options along with the redaction type.
|
|
2207
|
-
- `tokens` defaults to false.
|
|
2208
|
-
|
|
2209
|
-
Skyflow.RedactionTypes accepts four values:
|
|
2210
|
-
- `PLAIN_TEXT`
|
|
2211
|
-
- `MASKED`
|
|
2212
|
-
- `REDACTED`
|
|
2213
|
-
- `DEFAULT`
|
|
2214
2220
|
|
|
2215
|
-
|
|
2221
|
+
The SDK supports four events:
|
|
2216
2222
|
|
|
2217
|
-
|
|
2223
|
+
- `CHANGE`: Triggered when the Element's value changes.
|
|
2224
|
+
- `READY`: Triggered when the Element is fully rendered.
|
|
2225
|
+
- `FOCUS`: Triggered when the Element gains focus.
|
|
2226
|
+
- `BLUR`: Triggered when the Element loses focus.
|
|
2227
|
+
|
|
2228
|
+
The handler `function(state) => void` is a callback function you provide that's called when the event is fired with a state object that uses the following schema:
|
|
2218
2229
|
|
|
2219
2230
|
```javascript
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
],
|
|
2228
|
-
};
|
|
2231
|
+
state : {
|
|
2232
|
+
elementType: Skyflow.ElementType
|
|
2233
|
+
isEmpty: boolean
|
|
2234
|
+
isFocused: boolean
|
|
2235
|
+
isValid: boolean
|
|
2236
|
+
value: string
|
|
2237
|
+
}
|
|
2229
2238
|
```
|
|
2230
|
-
|
|
2239
|
+
`Note`: Events only include element values when in the state object when env is DEV. By default, value is an empty string.
|
|
2240
|
+
|
|
2241
|
+
### Example Usage of Event Listener on Composable Elements
|
|
2231
2242
|
|
|
2232
2243
|
```javascript
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2244
|
+
const containerOptions = {
|
|
2245
|
+
layout: [1],
|
|
2246
|
+
styles: {
|
|
2247
|
+
base: {
|
|
2248
|
+
border: '1px solid #eae8ee',
|
|
2249
|
+
padding: '10px 16px',
|
|
2250
|
+
borderRadius: '4px',
|
|
2251
|
+
margin: '12px 2px',
|
|
2252
|
+
}
|
|
2253
|
+
},
|
|
2254
|
+
errorTextStyles: {
|
|
2255
|
+
base: {
|
|
2256
|
+
color: 'red'
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2243
2260
|
|
|
2244
|
-
|
|
2245
|
-
],
|
|
2246
|
-
};
|
|
2247
|
-
```
|
|
2248
|
-
[Example usage (Skyflow IDs)](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/get-pure-js.html)
|
|
2261
|
+
const composableContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
|
|
2249
2262
|
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
},
|
|
2263
|
-
],
|
|
2263
|
+
const cvv = composableContainer.create({
|
|
2264
|
+
table: 'pii_fields',
|
|
2265
|
+
column: 'primary_card.cvv',
|
|
2266
|
+
type: Skyflow.ElementType.CVV,
|
|
2267
|
+
});
|
|
2268
|
+
|
|
2269
|
+
composableContainer.mount('#cvvContainer');
|
|
2270
|
+
|
|
2271
|
+
// Subscribing to CHANGE event, which gets triggered when element changes.
|
|
2272
|
+
cvv.on(Skyflow.EventName.CHANGE, state => {
|
|
2273
|
+
// Your implementation when Change event occurs.
|
|
2274
|
+
console.log(state);
|
|
2264
2275
|
});
|
|
2265
2276
|
```
|
|
2266
|
-
|
|
2277
|
+
|
|
2278
|
+
Sample Element state object when env is `DEV`
|
|
2267
2279
|
|
|
2268
2280
|
```javascript
|
|
2269
2281
|
{
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
"expiry_date": "11/2035",
|
|
2276
|
-
"fullname": "myname",
|
|
2277
|
-
"id": "f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9"
|
|
2278
|
-
},
|
|
2279
|
-
"table": "cards"
|
|
2280
|
-
}
|
|
2281
|
-
],
|
|
2282
|
-
"errors": [
|
|
2283
|
-
{
|
|
2284
|
-
"error": {
|
|
2285
|
-
"code": "404",
|
|
2286
|
-
"description": "No Records Found"
|
|
2287
|
-
},
|
|
2288
|
-
"ids": ["da26de53-95d5-4bdb-99db-8d8c66a35ff9"]
|
|
2289
|
-
}
|
|
2290
|
-
]
|
|
2282
|
+
elementType: 'CVV'
|
|
2283
|
+
isEmpty: false
|
|
2284
|
+
isFocused: true
|
|
2285
|
+
isValid: false
|
|
2286
|
+
value: '411'
|
|
2291
2287
|
}
|
|
2292
2288
|
```
|
|
2293
|
-
[Example usage (Unique column values)](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/get-pure-js.html)
|
|
2294
2289
|
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
records: [
|
|
2298
|
-
{
|
|
2299
|
-
table: "cards",
|
|
2300
|
-
redaction: RedactionType.PLAIN_TEXT,
|
|
2301
|
-
columnName: "card_id",
|
|
2302
|
-
columnValues: ["123", "456"],
|
|
2303
|
-
}
|
|
2304
|
-
],
|
|
2305
|
-
});
|
|
2306
|
-
```
|
|
2307
|
-
Sample response:
|
|
2290
|
+
Sample Element state object when env is `PROD`
|
|
2291
|
+
|
|
2308
2292
|
```javascript
|
|
2309
2293
|
{
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
"fullname": "myname",
|
|
2316
|
-
"id": "f8d2-b557-4c6b-a12c-c5ebfd9"
|
|
2317
|
-
},
|
|
2318
|
-
"table": "cards"
|
|
2319
|
-
},
|
|
2320
|
-
{
|
|
2321
|
-
"fields": {
|
|
2322
|
-
"card_id": "456",
|
|
2323
|
-
"expiry_date": "10/23",
|
|
2324
|
-
"fullname": "sam",
|
|
2325
|
-
"id": "da53-95d5-4bdb-99db-8d8c5ff9"
|
|
2326
|
-
},
|
|
2327
|
-
"table": "cards"
|
|
2328
|
-
}
|
|
2329
|
-
]
|
|
2294
|
+
elementType: 'CVV'
|
|
2295
|
+
isEmpty: false
|
|
2296
|
+
isFocused: true
|
|
2297
|
+
isValid: false
|
|
2298
|
+
value: ''
|
|
2330
2299
|
}
|
|
2331
2300
|
```
|
|
2332
2301
|
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
ids: [
|
|
2339
|
-
"f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9",
|
|
2340
|
-
"da26de53-95d5-4bdb-99db-8d8c66a35ff9"
|
|
2341
|
-
],
|
|
2342
|
-
table: "cards",
|
|
2343
|
-
},
|
|
2344
|
-
],
|
|
2345
|
-
}, { tokens: true });
|
|
2346
|
-
```
|
|
2347
|
-
Sample response:
|
|
2302
|
+
### Update composable elements
|
|
2303
|
+
You can update composable element properties with the `update` interface.
|
|
2304
|
+
|
|
2305
|
+
|
|
2306
|
+
The `update` interface takes the below object:
|
|
2348
2307
|
```javascript
|
|
2349
|
-
{
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
},
|
|
2360
|
-
{
|
|
2361
|
-
"fields": {
|
|
2362
|
-
"card_id": "d794b64c-e283-4fb8-8eef-9f6710730b69",
|
|
2363
|
-
"expiry_date": "ff848fc3-a093-4ed4-9414-877b74a33111",
|
|
2364
|
-
"fullname": "dfb6c247-3ee6-4fd2-8d1e-19d8e11c25ce",
|
|
2365
|
-
"id": "da53-95d5-4bdb-99db-8d8c5ff9"
|
|
2366
|
-
},
|
|
2367
|
-
"table": "cards"
|
|
2368
|
-
}
|
|
2369
|
-
]
|
|
2370
|
-
}
|
|
2308
|
+
const updateElement = {
|
|
2309
|
+
table: 'string', // Optional. The table this data belongs to.
|
|
2310
|
+
column: 'string', // Optional. The column this data belongs to.
|
|
2311
|
+
inputStyles: {}, // Optional. Styles applied to the form element.
|
|
2312
|
+
labelStyles: {}, // Optional. Styles for the label of the element.
|
|
2313
|
+
errorTextStyles: {}, // Optional. Styles for the errorText of element.
|
|
2314
|
+
label: 'string', // Optional. Label for the form element.
|
|
2315
|
+
placeholder: 'string', // Optional. Placeholder for the form element.
|
|
2316
|
+
validations: [], // Optional. Array of validation rules.
|
|
2317
|
+
};
|
|
2371
2318
|
```
|
|
2372
2319
|
|
|
2373
|
-
|
|
2320
|
+
Only include the properties that you want to update for the specified composable element.
|
|
2374
2321
|
|
|
2375
|
-
|
|
2322
|
+
Properties your provided when you created the element remain the same until you explicitly update them.
|
|
2376
2323
|
|
|
2377
|
-
|
|
2378
|
-
To start, create a container using the `container(Skyflow.ContainerType)` method of the Skyflow client as shown below.
|
|
2324
|
+
`Note`: You can't update the `type` property of an element.
|
|
2379
2325
|
|
|
2326
|
+
### End to end example
|
|
2380
2327
|
```javascript
|
|
2381
|
-
const
|
|
2328
|
+
const containerOptions = { layout: [2, 1] };
|
|
2329
|
+
|
|
2330
|
+
// Create a composable container.
|
|
2331
|
+
const composableContainer = skyflowClient.container(
|
|
2332
|
+
Skyflow.ContainerType.COMPOSABLE,
|
|
2333
|
+
containerOptions
|
|
2334
|
+
);
|
|
2335
|
+
|
|
2336
|
+
const stylesOptions = {
|
|
2337
|
+
inputStyles: {
|
|
2338
|
+
base: {
|
|
2339
|
+
fontFamily: 'Inter',
|
|
2340
|
+
fontStyle: 'normal',
|
|
2341
|
+
fontWeight: 400,
|
|
2342
|
+
fontSize: '14px',
|
|
2343
|
+
lineHeight: '21px',
|
|
2344
|
+
width: '294px',
|
|
2345
|
+
},
|
|
2346
|
+
},
|
|
2347
|
+
labelStyles: {},
|
|
2348
|
+
errorTextStyles: {
|
|
2349
|
+
base: {},
|
|
2350
|
+
},
|
|
2351
|
+
};
|
|
2352
|
+
|
|
2353
|
+
// Create composable elements.
|
|
2354
|
+
const cardHolderNameElement = composableContainer.create({
|
|
2355
|
+
table: 'pii_fields',
|
|
2356
|
+
column: 'first_name',
|
|
2357
|
+
...stylesOptions,
|
|
2358
|
+
placeholder: 'Cardholder Name',
|
|
2359
|
+
type: Skyflow.ElementType.CARDHOLDER_NAME,
|
|
2360
|
+
});
|
|
2361
|
+
|
|
2362
|
+
|
|
2363
|
+
const cardNumberElement = composableContainer.create({
|
|
2364
|
+
table: 'pii_fields',
|
|
2365
|
+
column: 'card_number',
|
|
2366
|
+
...stylesOptions,
|
|
2367
|
+
placeholder: 'Card Number',
|
|
2368
|
+
type: Skyflow.ElementType.CARD_NUMBER,
|
|
2369
|
+
});
|
|
2370
|
+
|
|
2371
|
+
const cvvElement = composableContainer.create({
|
|
2372
|
+
table: 'pii_fields',
|
|
2373
|
+
column: 'cvv',
|
|
2374
|
+
...stylesOptions,
|
|
2375
|
+
placeholder: 'CVV',
|
|
2376
|
+
type: Skyflow.ElementType.CVV,
|
|
2377
|
+
});
|
|
2378
|
+
|
|
2379
|
+
// Mount the composable container.
|
|
2380
|
+
composableContainer.mount('#compostableContainer'); // Assumes there is a div with id='#composableContainer' in the webpage.
|
|
2381
|
+
|
|
2382
|
+
// ...
|
|
2383
|
+
|
|
2384
|
+
// Update validations property on cvvElement.
|
|
2385
|
+
cvvElement.update({
|
|
2386
|
+
validations: [{
|
|
2387
|
+
type: Skyflow.ValidationRuleType.LENGTH_MATCH_RULE,
|
|
2388
|
+
params: {
|
|
2389
|
+
max: 3,
|
|
2390
|
+
error: 'cvv must be 3 digits',
|
|
2391
|
+
},
|
|
2392
|
+
}]
|
|
2393
|
+
})
|
|
2394
|
+
|
|
2395
|
+
// Update label, placeholder properties on cardHolderNameElement.
|
|
2396
|
+
cardHolderNameElement.update({
|
|
2397
|
+
label: 'CARDHOLDER NAME',
|
|
2398
|
+
placeholder: 'Eg: John'
|
|
2399
|
+
});
|
|
2400
|
+
|
|
2401
|
+
// Update table, column, inputStyles properties on cardNumberElement.
|
|
2402
|
+
cardNumberElement.update({
|
|
2403
|
+
table:'cards',
|
|
2404
|
+
column:'card_number',
|
|
2405
|
+
inputStyles:{
|
|
2406
|
+
base:{
|
|
2407
|
+
color:'blue'
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
});
|
|
2411
|
+
|
|
2412
|
+
|
|
2413
|
+
```
|
|
2414
|
+
### Set an event listener on a composable container
|
|
2415
|
+
Currently, the SDK supports one event:
|
|
2416
|
+
- `SUBMIT`: Triggered when the `Enter` key is pressed in any container element.
|
|
2417
|
+
|
|
2418
|
+
The handler `function(void) => void` is a callback function you provide that's called when the `SUBMIT' event fires.
|
|
2419
|
+
|
|
2420
|
+
### Example
|
|
2421
|
+
```javascript
|
|
2422
|
+
const containerOptions = { layout: [1] }
|
|
2423
|
+
|
|
2424
|
+
// Creating a composable container.
|
|
2425
|
+
const composableContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
|
|
2426
|
+
|
|
2427
|
+
// Creating the element.
|
|
2428
|
+
const cvv = composableContainer.create({
|
|
2429
|
+
table: 'pii_fields',
|
|
2430
|
+
column: 'primary_card.cvv',
|
|
2431
|
+
type: Skyflow.ElementType.CVV,
|
|
2432
|
+
});
|
|
2433
|
+
|
|
2434
|
+
// Mounting the container.
|
|
2435
|
+
composableContainer.mount('#cvvContainer');
|
|
2436
|
+
|
|
2437
|
+
// Subscribing to the `SUBMIT` event, which gets triggered when the user hits `enter` key in any container element input.
|
|
2438
|
+
composableContainer.on(Skyflow.EventName.SUBMIT, ()=> {
|
|
2439
|
+
// Your implementation when the SUBMIT(enter) event occurs.
|
|
2440
|
+
console.log('Submit Event Listener is being Triggered.');
|
|
2441
|
+
});
|
|
2442
|
+
```
|
|
2443
|
+
|
|
2444
|
+
## Using Skyflow Composable File Element to upload a file
|
|
2445
|
+
You can upload binary files to a vault using the Skyflow File Element. Use the following steps to securely upload a file.
|
|
2446
|
+
### Step 1: Create a container
|
|
2447
|
+
|
|
2448
|
+
Create a container for the form elements using the container(Skyflow.ContainerType) method of the Skyflow client:
|
|
2449
|
+
|
|
2450
|
+
```javascript
|
|
2451
|
+
const containerOptions = { layout: [1] }
|
|
2452
|
+
|
|
2453
|
+
// Creating a composable container.
|
|
2454
|
+
const composableContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
|
|
2455
|
+
```
|
|
2456
|
+
|
|
2457
|
+
### Step 2: Create a File Element
|
|
2458
|
+
|
|
2459
|
+
Skyflow Collect Elements are defined as follows:
|
|
2460
|
+
|
|
2461
|
+
```javascript
|
|
2462
|
+
const collectElement = {
|
|
2463
|
+
type: Skyflow.ElementType.FILE_INPUT, // Skyflow.ElementType enum.
|
|
2464
|
+
table: 'string', // The table this data belongs to.
|
|
2465
|
+
column: 'string', // The column into which this data should be inserted.
|
|
2466
|
+
skyflowID: 'string', // The skyflow_id of the record.
|
|
2467
|
+
inputStyles: {}, // Optional, styles that should be applied to the form element.
|
|
2468
|
+
labelStyles: {}, // Optional, styles that will be applied to the label of the collect element.
|
|
2469
|
+
errorTextStyles:{}, // Optional, styles that will be applied to the errorText of the collect element.
|
|
2470
|
+
}
|
|
2471
|
+
```
|
|
2472
|
+
The `table` and `column` fields indicate which table and column the Element corresponds to.
|
|
2473
|
+
|
|
2474
|
+
`skyflowID` indicates the record that stores the file.
|
|
2475
|
+
|
|
2476
|
+
**Notes**:
|
|
2477
|
+
- `skyflowID` is required while creating File element
|
|
2478
|
+
- Use period-delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`).
|
|
2479
|
+
|
|
2480
|
+
### Step 3: Mount Container to the DOM
|
|
2481
|
+
Mount Elements for file upload to the DOM the same way as Elements used for collecting data. Refer to Step 3 of the [section above](#step-3-mount-container-to-the-dom).
|
|
2482
|
+
|
|
2483
|
+
### Step 4: Collect data from elements
|
|
2484
|
+
|
|
2485
|
+
When you're ready to upload the file, call the `uploadFiles()` method on the container object.
|
|
2486
|
+
|
|
2487
|
+
```javascript
|
|
2488
|
+
composableContainer.uploadFiles();
|
|
2489
|
+
```
|
|
2490
|
+
### File upload limitations:
|
|
2491
|
+
|
|
2492
|
+
- Only non-executable file are allowed to be uploaded.
|
|
2493
|
+
- Files must have a maximum size of 32 MB
|
|
2494
|
+
- File columns can't enable tokenization, redaction, or arrays.
|
|
2495
|
+
- Re-uploading a file overwrites previously uploaded data.
|
|
2496
|
+
- Partial uploads or resuming a previous upload isn't supported.
|
|
2497
|
+
|
|
2498
|
+
### End-to-end file upload
|
|
2499
|
+
|
|
2500
|
+
```javascript
|
|
2501
|
+
// Step 1.
|
|
2502
|
+
const containerOptions = { layout: [1] }
|
|
2503
|
+
|
|
2504
|
+
// Creating a composable container.
|
|
2505
|
+
const container = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
|
|
2506
|
+
|
|
2507
|
+
// Step 2.
|
|
2508
|
+
const element = container.create({
|
|
2509
|
+
table: 'pii_fields',
|
|
2510
|
+
column: 'file',
|
|
2511
|
+
skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
|
|
2512
|
+
inputstyles: {
|
|
2513
|
+
base: {
|
|
2514
|
+
color: '#1d1d1d',
|
|
2515
|
+
},
|
|
2516
|
+
},
|
|
2517
|
+
labelStyles: {
|
|
2518
|
+
base: {
|
|
2519
|
+
fontSize: '12px',
|
|
2520
|
+
fontWeight: 'bold',
|
|
2521
|
+
},
|
|
2522
|
+
},
|
|
2523
|
+
errorTextStyles: {
|
|
2524
|
+
base: {
|
|
2525
|
+
color: '#f44336',
|
|
2526
|
+
},
|
|
2527
|
+
},
|
|
2528
|
+
type: Skyflow.ElementType.FILE_INPUT,
|
|
2529
|
+
});
|
|
2530
|
+
|
|
2531
|
+
// Step 3.
|
|
2532
|
+
container.mount('#file'); // Assumes there is a div with id='#file' in the webpage.
|
|
2533
|
+
|
|
2534
|
+
// Step 4.
|
|
2535
|
+
container.uploadFiles();
|
|
2536
|
+
```
|
|
2537
|
+
|
|
2538
|
+
**Sample Response :**
|
|
2539
|
+
```javascript
|
|
2540
|
+
{
|
|
2541
|
+
fileUploadResponse: [
|
|
2542
|
+
{
|
|
2543
|
+
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
|
|
2544
|
+
}
|
|
2545
|
+
]
|
|
2546
|
+
}
|
|
2547
|
+
```
|
|
2548
|
+
### File upload with options:
|
|
2549
|
+
|
|
2550
|
+
Along with fileElementInput, you can define other options in the Options object as described below:
|
|
2551
|
+
```js
|
|
2552
|
+
const options = {
|
|
2553
|
+
allowedFileType: String[], // Optional, indicates the allowed file types for upload
|
|
2554
|
+
}
|
|
2555
|
+
```
|
|
2556
|
+
`allowedFileType`: An array of string value that indicates the allowedFileTypes to be uploaded.
|
|
2557
|
+
|
|
2558
|
+
#### File upload with options example
|
|
2559
|
+
|
|
2560
|
+
```javascript
|
|
2561
|
+
// Create collect Container.
|
|
2562
|
+
const containerOptions = { layout: [1] }
|
|
2563
|
+
|
|
2564
|
+
// Creating a composable container.
|
|
2565
|
+
const collectContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
|
|
2566
|
+
|
|
2567
|
+
// Create collect elements.
|
|
2568
|
+
const cardNumberElement = collectContainer.create({
|
|
2569
|
+
table: 'newTable',
|
|
2570
|
+
column: 'card_number',
|
|
2571
|
+
inputstyles: {
|
|
2572
|
+
base: {
|
|
2573
|
+
color: '#1d1d1d',
|
|
2574
|
+
},
|
|
2575
|
+
},
|
|
2576
|
+
labelStyles: {
|
|
2577
|
+
base: {
|
|
2578
|
+
fontSize: '12px',
|
|
2579
|
+
fontWeight: 'bold',
|
|
2580
|
+
},
|
|
2581
|
+
},
|
|
2582
|
+
errorTextStyles: {
|
|
2583
|
+
base: {
|
|
2584
|
+
color: '#f44336',
|
|
2585
|
+
},
|
|
2586
|
+
},
|
|
2587
|
+
placeholder: 'card number',
|
|
2588
|
+
label: 'Card Number',
|
|
2589
|
+
type: Skyflow.ElementType.CARD_NUMBER,
|
|
2590
|
+
});
|
|
2591
|
+
const options = {
|
|
2592
|
+
allowedFileType: [".pdf",".png"];
|
|
2593
|
+
};
|
|
2594
|
+
const fileElement = collectContainer.create({
|
|
2595
|
+
table: 'newTable',
|
|
2596
|
+
column: 'file',
|
|
2597
|
+
skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
|
|
2598
|
+
inputstyles: {
|
|
2599
|
+
base: {
|
|
2600
|
+
color: '#1d1d1d',
|
|
2601
|
+
},
|
|
2602
|
+
},
|
|
2603
|
+
labelStyles: {
|
|
2604
|
+
base: {
|
|
2605
|
+
fontSize: '12px',
|
|
2606
|
+
fontWeight: 'bold',
|
|
2607
|
+
},
|
|
2608
|
+
},
|
|
2609
|
+
errorTextStyles: {
|
|
2610
|
+
base: {
|
|
2611
|
+
color: '#f44336',
|
|
2612
|
+
},
|
|
2613
|
+
},
|
|
2614
|
+
type: Skyflow.ElementType.FILE_INPUT,
|
|
2615
|
+
},
|
|
2616
|
+
options
|
|
2617
|
+
);
|
|
2618
|
+
|
|
2619
|
+
// Mount the elements.
|
|
2620
|
+
collectContainer.mount('#collectContainer');
|
|
2621
|
+
|
|
2622
|
+
// Collect and upload methods.
|
|
2623
|
+
collectContainer.collect({});
|
|
2624
|
+
collectContainer.uploadFiles();
|
|
2625
|
+
|
|
2626
|
+
```
|
|
2627
|
+
**Sample Response for collect():**
|
|
2628
|
+
```javascript
|
|
2629
|
+
{
|
|
2630
|
+
"records": [
|
|
2631
|
+
{
|
|
2632
|
+
"table": "newTable",
|
|
2633
|
+
"fields": {
|
|
2634
|
+
"card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
]
|
|
2638
|
+
}
|
|
2639
|
+
```
|
|
2640
|
+
**Sample Response for file uploadFiles() :**
|
|
2641
|
+
```javascript
|
|
2642
|
+
{
|
|
2643
|
+
"fileUploadResponse": [
|
|
2644
|
+
{
|
|
2645
|
+
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
|
|
2646
|
+
}
|
|
2647
|
+
]
|
|
2648
|
+
}
|
|
2649
|
+
```
|
|
2650
|
+
#### File upload with additional elements
|
|
2651
|
+
|
|
2652
|
+
```javascript
|
|
2653
|
+
// Create collect Container.
|
|
2654
|
+
const containerOptions = { layout: [1,1] }
|
|
2655
|
+
|
|
2656
|
+
// Creating a composable container.
|
|
2657
|
+
const collectContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
|
|
2658
|
+
|
|
2659
|
+
// Create collect elements.
|
|
2660
|
+
const cardNumberElement = collectContainer.create({
|
|
2661
|
+
table: 'newTable',
|
|
2662
|
+
column: 'card_number',
|
|
2663
|
+
inputstyles: {
|
|
2664
|
+
base: {
|
|
2665
|
+
color: '#1d1d1d',
|
|
2666
|
+
},
|
|
2667
|
+
},
|
|
2668
|
+
labelStyles: {
|
|
2669
|
+
base: {
|
|
2670
|
+
fontSize: '12px',
|
|
2671
|
+
fontWeight: 'bold',
|
|
2672
|
+
},
|
|
2673
|
+
},
|
|
2674
|
+
errorTextStyles: {
|
|
2675
|
+
base: {
|
|
2676
|
+
color: '#f44336',
|
|
2677
|
+
},
|
|
2678
|
+
},
|
|
2679
|
+
placeholder: 'card number',
|
|
2680
|
+
label: 'Card Number',
|
|
2681
|
+
type: Skyflow.ElementType.CARD_NUMBER,
|
|
2682
|
+
});
|
|
2683
|
+
|
|
2684
|
+
const fileElement = collectContainer.create({
|
|
2685
|
+
table: 'newTable',
|
|
2686
|
+
column: 'file',
|
|
2687
|
+
skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
|
|
2688
|
+
inputstyles: {
|
|
2689
|
+
base: {
|
|
2690
|
+
color: '#1d1d1d',
|
|
2691
|
+
},
|
|
2692
|
+
},
|
|
2693
|
+
labelStyles: {
|
|
2694
|
+
base: {
|
|
2695
|
+
fontSize: '12px',
|
|
2696
|
+
fontWeight: 'bold',
|
|
2697
|
+
},
|
|
2698
|
+
},
|
|
2699
|
+
errorTextStyles: {
|
|
2700
|
+
base: {
|
|
2701
|
+
color: '#f44336',
|
|
2702
|
+
},
|
|
2703
|
+
},
|
|
2704
|
+
type: Skyflow.ElementType.FILE_INPUT,
|
|
2705
|
+
});
|
|
2706
|
+
|
|
2707
|
+
// Mount the elements.
|
|
2708
|
+
cardNumberElement.mount('#collectCardNumber');
|
|
2709
|
+
fileElement.mount('#collectFile');
|
|
2710
|
+
|
|
2711
|
+
// Collect and upload methods.
|
|
2712
|
+
collectContainer.collect({});
|
|
2713
|
+
collectContainer.uploadFiles();
|
|
2714
|
+
|
|
2715
|
+
```
|
|
2716
|
+
**Sample Response for collect():**
|
|
2717
|
+
```javascript
|
|
2718
|
+
{
|
|
2719
|
+
"records": [
|
|
2720
|
+
{
|
|
2721
|
+
"table": "newTable",
|
|
2722
|
+
"fields": {
|
|
2723
|
+
"card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
]
|
|
2727
|
+
}
|
|
2728
|
+
```
|
|
2729
|
+
**Sample Response for file uploadFiles() :**
|
|
2730
|
+
```javascript
|
|
2731
|
+
{
|
|
2732
|
+
"fileUploadResponse": [
|
|
2733
|
+
{
|
|
2734
|
+
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
|
|
2735
|
+
}
|
|
2736
|
+
]
|
|
2737
|
+
}
|
|
2738
|
+
```
|
|
2739
|
+
|
|
2740
|
+
Note: File name should contain only alphanumeric characters and !-_.*()
|
|
2741
|
+
|
|
2742
|
+
|
|
2743
|
+
## Using Skyflow Composable File Element to upload multiple files
|
|
2744
|
+
You can upload binary files to a vault using the Skyflow File Element. Use the following steps to securely upload a file.
|
|
2745
|
+
### Step 1: Create a container
|
|
2746
|
+
|
|
2747
|
+
Create a container for the form elements using the container(Skyflow.ContainerType) method of the Skyflow client:
|
|
2748
|
+
|
|
2749
|
+
```javascript
|
|
2750
|
+
const containerOptions = { layout: [1] }
|
|
2751
|
+
|
|
2752
|
+
// Creating a composable container.
|
|
2753
|
+
const composableContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
|
|
2754
|
+
```
|
|
2755
|
+
|
|
2756
|
+
### Step 2: Create a File Element
|
|
2757
|
+
|
|
2758
|
+
Skyflow Collect Elements are defined as follows:
|
|
2759
|
+
|
|
2760
|
+
```javascript
|
|
2761
|
+
const collectElement = {
|
|
2762
|
+
type: Skyflow.ElementType.MULTI_FILE_INPUT, // Skyflow.ElementType enum.
|
|
2763
|
+
table: 'string', // The table this data belongs to.
|
|
2764
|
+
column: 'string', // The column into which this data should be inserted.
|
|
2765
|
+
inputStyles: {}, // Optional, styles that should be applied to the form element.
|
|
2766
|
+
labelStyles: {}, // Optional, styles that will be applied to the label of the collect element.
|
|
2767
|
+
errorTextStyles:{}, // Optional, styles that will be applied to the errorText of the collect element.
|
|
2768
|
+
}
|
|
2769
|
+
```
|
|
2770
|
+
The `table` and `column` fields indicate which table and column the Element corresponds to.
|
|
2771
|
+
|
|
2772
|
+
**Notes**:
|
|
2773
|
+
- Use period-delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`).
|
|
2774
|
+
|
|
2775
|
+
### Step 3: Mount container to the DOM
|
|
2776
|
+
Elements used for rendering files are mounted to the DOM the same way as Elements used for collecting data. Refer to Step 3 of the [section above](#step-3-mount-elements-to-the-dom-1).
|
|
2777
|
+
|
|
2778
|
+
### Step 4: Collect data from elements
|
|
2779
|
+
|
|
2780
|
+
When you're ready to upload the file, call the `uploadMultipleFiles()` method on the element.
|
|
2781
|
+
|
|
2782
|
+
```javascript
|
|
2783
|
+
const metaData = {card_number: '123'} // Optional: used to generate Skyflow IDs, and upload files to those IDs
|
|
2784
|
+
|
|
2785
|
+
element.uploadMultipleFiles();
|
|
2786
|
+
```
|
|
2787
|
+
Note:
|
|
2788
|
+
- If `MetaData` is provided, that will be used to generate Skyflow IDs, and upload files to those IDs
|
|
2789
|
+
- If `MetaData` is not provided, the files will be uploaded as a new record.
|
|
2790
|
+
|
|
2791
|
+
### File upload limitations:
|
|
2792
|
+
|
|
2793
|
+
- Only non-executable file are allowed to be uploaded.
|
|
2794
|
+
- Files must have a maximum size of 32 MB
|
|
2795
|
+
- File columns can't enable tokenization, redaction, or arrays.
|
|
2796
|
+
- Re-uploading a file overwrites previously uploaded data.
|
|
2797
|
+
- Partial uploads or resuming a previous upload isn't supported.
|
|
2798
|
+
|
|
2799
|
+
### End-to-end file upload
|
|
2800
|
+
|
|
2801
|
+
```javascript
|
|
2802
|
+
// Step 1.
|
|
2803
|
+
const containerOptions = { layout: [1] }
|
|
2804
|
+
|
|
2805
|
+
// Creating a composable container.
|
|
2806
|
+
const container = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
|
|
2807
|
+
|
|
2808
|
+
// Step 2.
|
|
2809
|
+
const element = container.create({
|
|
2810
|
+
table: 'pii_fields',
|
|
2811
|
+
column: 'file',
|
|
2812
|
+
skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
|
|
2813
|
+
inputstyles: {
|
|
2814
|
+
base: {
|
|
2815
|
+
color: '#1d1d1d',
|
|
2816
|
+
},
|
|
2817
|
+
},
|
|
2818
|
+
labelStyles: {
|
|
2819
|
+
base: {
|
|
2820
|
+
fontSize: '12px',
|
|
2821
|
+
fontWeight: 'bold',
|
|
2822
|
+
},
|
|
2823
|
+
},
|
|
2824
|
+
errorTextStyles: {
|
|
2825
|
+
base: {
|
|
2826
|
+
color: '#f44336',
|
|
2827
|
+
},
|
|
2828
|
+
},
|
|
2829
|
+
type: Skyflow.ElementType.MULTI_FILE_INPUT,
|
|
2830
|
+
});
|
|
2831
|
+
|
|
2832
|
+
// Step 3.
|
|
2833
|
+
container.mount('#file'); // Assumes there is a div with id='#file' in the webpage.
|
|
2834
|
+
|
|
2835
|
+
// Step 4.
|
|
2836
|
+
element.uploadMultipleFiles();
|
|
2837
|
+
```
|
|
2838
|
+
|
|
2839
|
+
**Sample Response :**
|
|
2840
|
+
```javascript
|
|
2841
|
+
{
|
|
2842
|
+
fileUploadResponse: [
|
|
2843
|
+
{
|
|
2844
|
+
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
|
|
2845
|
+
}
|
|
2846
|
+
]
|
|
2847
|
+
}
|
|
2848
|
+
```
|
|
2849
|
+
### File upload with options:
|
|
2850
|
+
|
|
2851
|
+
Along with fileElementInput, you can define other options in the Options object as described below:
|
|
2852
|
+
```js
|
|
2853
|
+
const options = {
|
|
2854
|
+
allowedFileType: String[], // Optional, indicates the allowed file types for upload
|
|
2855
|
+
}
|
|
2856
|
+
```
|
|
2857
|
+
`allowedFileType`: An array of string value that indicates the allowedFileTypes to be uploaded.
|
|
2858
|
+
|
|
2859
|
+
#### File upload with options example
|
|
2860
|
+
|
|
2861
|
+
```javascript
|
|
2862
|
+
// Create collect Container.
|
|
2863
|
+
const containerOptions = { layout: [1] }
|
|
2864
|
+
|
|
2865
|
+
// Creating a composable container.
|
|
2866
|
+
const collectContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
|
|
2867
|
+
|
|
2868
|
+
// Create collect elements.
|
|
2869
|
+
const cardNumberElement = collectContainer.create({
|
|
2870
|
+
table: 'newTable',
|
|
2871
|
+
column: 'card_number',
|
|
2872
|
+
inputstyles: {
|
|
2873
|
+
base: {
|
|
2874
|
+
color: '#1d1d1d',
|
|
2875
|
+
},
|
|
2876
|
+
},
|
|
2877
|
+
labelStyles: {
|
|
2878
|
+
base: {
|
|
2879
|
+
fontSize: '12px',
|
|
2880
|
+
fontWeight: 'bold',
|
|
2881
|
+
},
|
|
2882
|
+
},
|
|
2883
|
+
errorTextStyles: {
|
|
2884
|
+
base: {
|
|
2885
|
+
color: '#f44336',
|
|
2886
|
+
},
|
|
2887
|
+
},
|
|
2888
|
+
placeholder: 'card number',
|
|
2889
|
+
label: 'Card Number',
|
|
2890
|
+
type: Skyflow.ElementType.CARD_NUMBER,
|
|
2891
|
+
});
|
|
2892
|
+
const options = {
|
|
2893
|
+
allowedFileType: [".pdf",".png"];
|
|
2894
|
+
};
|
|
2895
|
+
const fileElement = collectContainer.create({
|
|
2896
|
+
table: 'newTable',
|
|
2897
|
+
column: 'file',
|
|
2898
|
+
skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
|
|
2899
|
+
inputstyles: {
|
|
2900
|
+
base: {
|
|
2901
|
+
color: '#1d1d1d',
|
|
2902
|
+
},
|
|
2903
|
+
},
|
|
2904
|
+
labelStyles: {
|
|
2905
|
+
base: {
|
|
2906
|
+
fontSize: '12px',
|
|
2907
|
+
fontWeight: 'bold',
|
|
2908
|
+
},
|
|
2909
|
+
},
|
|
2910
|
+
errorTextStyles: {
|
|
2911
|
+
base: {
|
|
2912
|
+
color: '#f44336',
|
|
2913
|
+
},
|
|
2914
|
+
},
|
|
2915
|
+
type: Skyflow.ElementType.MULTI_FILE_INPUT,
|
|
2916
|
+
},
|
|
2917
|
+
options
|
|
2918
|
+
);
|
|
2919
|
+
|
|
2920
|
+
// Mount the elements.
|
|
2921
|
+
collectContainer.mount('#collectContainer');
|
|
2922
|
+
|
|
2923
|
+
// Collect and upload methods.
|
|
2924
|
+
collectContainer.collect({});
|
|
2925
|
+
fileElement.uploadMultipleFiles();
|
|
2926
|
+
|
|
2927
|
+
```
|
|
2928
|
+
**Sample Response for collect():**
|
|
2929
|
+
```javascript
|
|
2930
|
+
{
|
|
2931
|
+
"records": [
|
|
2932
|
+
{
|
|
2933
|
+
"table": "newTable",
|
|
2934
|
+
"fields": {
|
|
2935
|
+
"card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
]
|
|
2939
|
+
}
|
|
2940
|
+
```
|
|
2941
|
+
**Sample Response for file uploadFiles() :**
|
|
2942
|
+
```javascript
|
|
2943
|
+
{
|
|
2944
|
+
"fileUploadResponse": [
|
|
2945
|
+
{
|
|
2946
|
+
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
|
|
2947
|
+
}
|
|
2948
|
+
]
|
|
2949
|
+
}
|
|
2950
|
+
```
|
|
2951
|
+
#### File upload with additional elements
|
|
2952
|
+
|
|
2953
|
+
```javascript
|
|
2954
|
+
// Create collect Container.
|
|
2955
|
+
const containerOptions = { layout: [1,1] }
|
|
2956
|
+
|
|
2957
|
+
// Creating a composable container.
|
|
2958
|
+
const collectContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
|
|
2959
|
+
|
|
2960
|
+
// Create collect elements.
|
|
2961
|
+
const cardNumberElement = collectContainer.create({
|
|
2962
|
+
table: 'newTable',
|
|
2963
|
+
column: 'card_number',
|
|
2964
|
+
inputstyles: {
|
|
2965
|
+
base: {
|
|
2966
|
+
color: '#1d1d1d',
|
|
2967
|
+
},
|
|
2968
|
+
},
|
|
2969
|
+
labelStyles: {
|
|
2970
|
+
base: {
|
|
2971
|
+
fontSize: '12px',
|
|
2972
|
+
fontWeight: 'bold',
|
|
2973
|
+
},
|
|
2974
|
+
},
|
|
2975
|
+
errorTextStyles: {
|
|
2976
|
+
base: {
|
|
2977
|
+
color: '#f44336',
|
|
2978
|
+
},
|
|
2979
|
+
},
|
|
2980
|
+
placeholder: 'card number',
|
|
2981
|
+
label: 'Card Number',
|
|
2982
|
+
type: Skyflow.ElementType.CARD_NUMBER,
|
|
2983
|
+
});
|
|
2984
|
+
|
|
2985
|
+
const fileElement = collectContainer.create({
|
|
2986
|
+
table: 'newTable',
|
|
2987
|
+
column: 'file',
|
|
2988
|
+
skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
|
|
2989
|
+
inputstyles: {
|
|
2990
|
+
base: {
|
|
2991
|
+
color: '#1d1d1d',
|
|
2992
|
+
},
|
|
2993
|
+
},
|
|
2994
|
+
labelStyles: {
|
|
2995
|
+
base: {
|
|
2996
|
+
fontSize: '12px',
|
|
2997
|
+
fontWeight: 'bold',
|
|
2998
|
+
},
|
|
2999
|
+
},
|
|
3000
|
+
errorTextStyles: {
|
|
3001
|
+
base: {
|
|
3002
|
+
color: '#f44336',
|
|
3003
|
+
},
|
|
3004
|
+
},
|
|
3005
|
+
type: Skyflow.ElementType.MULTI_FILE_INPUT,
|
|
3006
|
+
});
|
|
3007
|
+
|
|
3008
|
+
// Mount the elements.
|
|
3009
|
+
collectContainer.mount('#collectContainer');
|
|
3010
|
+
|
|
3011
|
+
// Collect and upload methods.
|
|
3012
|
+
collectContainer.collect({});
|
|
3013
|
+
fileElement.uploadMultipleFiles();
|
|
3014
|
+
|
|
3015
|
+
```
|
|
3016
|
+
**Sample Response for collect():**
|
|
3017
|
+
```javascript
|
|
3018
|
+
{
|
|
3019
|
+
"records": [
|
|
3020
|
+
{
|
|
3021
|
+
"table": "newTable",
|
|
3022
|
+
"fields": {
|
|
3023
|
+
"card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
|
|
3024
|
+
}
|
|
3025
|
+
}
|
|
3026
|
+
]
|
|
3027
|
+
}
|
|
3028
|
+
```
|
|
3029
|
+
**Sample Response for file uploadFiles() :**
|
|
3030
|
+
```javascript
|
|
3031
|
+
{
|
|
3032
|
+
"fileUploadResponse": [
|
|
3033
|
+
{
|
|
3034
|
+
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
|
|
3035
|
+
},
|
|
3036
|
+
{
|
|
3037
|
+
"skyflow_id": "546eaa6c-5c15-4513-aa15-29f50babe809"
|
|
3038
|
+
}
|
|
3039
|
+
]
|
|
3040
|
+
}
|
|
3041
|
+
```
|
|
3042
|
+
Note: File name should contain only alphanumeric characters and !-_.*()
|
|
3043
|
+
|
|
3044
|
+
---
|
|
3045
|
+
|
|
3046
|
+
|
|
3047
|
+
# Securely revealing data client-side
|
|
3048
|
+
- [**Retrieving data from the vault**](#retrieving-data-from-the-vault)
|
|
3049
|
+
- [**Using Skyflow Elements to reveal data**](#using-skyflow-elements-to-reveal-data)
|
|
3050
|
+
- [**UI Error for Reveal Elements**](#ui-error-for-reveal-elements)
|
|
3051
|
+
- [**Set token for Reveal Elements**](#set-token-for-reveal-elements)
|
|
3052
|
+
- [**Set and clear altText for Reveal Elements**](#set-and-clear-alttext-for-reveal-elements)
|
|
3053
|
+
- [**Render a file with a File Element**](#render-a-file-with-a-file-element)
|
|
3054
|
+
- [**Update Reveal Elements**](#update-reveal-elements)
|
|
3055
|
+
- [**Using Composable Reveal Elements to reveal data**](#using-composable-reveal-elements-to-reveal-data)
|
|
3056
|
+
- [**Update Composable Reveal Elements**](#update-reveal-composable-elements)
|
|
3057
|
+
- [**Render a file with a composable file element**](#render-a-file-with-a-composable-file-element)
|
|
3058
|
+
|
|
3059
|
+
|
|
3060
|
+
## Retrieving data from the vault
|
|
3061
|
+
|
|
3062
|
+
For non-PCI use-cases, retrieving data from the vault and revealing it in the browser can be done either using the SkyflowID's, unique column values or tokens as described below
|
|
3063
|
+
|
|
3064
|
+
- ### Using Skyflow tokens
|
|
3065
|
+
In order to retrieve data from your vault using tokens that you have previously generated for that data, you can use the `detokenize(records)` method. The records parameter takes a JSON object that contains `records` to be fetched as shown below.
|
|
3066
|
+
|
|
3067
|
+
```javascript
|
|
3068
|
+
const records = {
|
|
3069
|
+
records: [
|
|
3070
|
+
{
|
|
3071
|
+
token: 'string', // Token for the record to be fetched.
|
|
3072
|
+
redaction: RedactionType // Optional. Redaction to be applied for retrieved data.
|
|
3073
|
+
},
|
|
3074
|
+
],
|
|
3075
|
+
};
|
|
3076
|
+
|
|
3077
|
+
Note: If you do not provide a redaction type, RedactionType.PLAIN_TEXT is the default.
|
|
3078
|
+
|
|
3079
|
+
skyflow.detokenize(records);
|
|
3080
|
+
```
|
|
3081
|
+
An [example](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/pure-js.html) of a detokenize call:
|
|
3082
|
+
|
|
3083
|
+
```javascript
|
|
3084
|
+
skyflow.detokenize({
|
|
3085
|
+
records: [
|
|
3086
|
+
{
|
|
3087
|
+
token: '131e70dc-6f76-4319-bdd3-96281e051051',
|
|
3088
|
+
},
|
|
3089
|
+
{
|
|
3090
|
+
token: '1r434532-6f76-4319-bdd3-96281e051051',
|
|
3091
|
+
redaction: Skyflow.RedactionType.MASKED
|
|
3092
|
+
}
|
|
3093
|
+
],
|
|
3094
|
+
});
|
|
3095
|
+
```
|
|
3096
|
+
|
|
3097
|
+
The sample response:
|
|
3098
|
+
```javascript
|
|
3099
|
+
{
|
|
3100
|
+
"records": [
|
|
3101
|
+
{
|
|
3102
|
+
"token": "131e70dc-6f76-4319-bdd3-96281e051051",
|
|
3103
|
+
"value": "1990-01-01",
|
|
3104
|
+
"valueType": "STRING"
|
|
3105
|
+
},
|
|
3106
|
+
{
|
|
3107
|
+
"token": "1r434532-6f76-4319-bdd3-96281e051051",
|
|
3108
|
+
"value": "xxxxxxer",
|
|
3109
|
+
"valueType": "STRING"
|
|
3110
|
+
}
|
|
3111
|
+
]
|
|
3112
|
+
}
|
|
3113
|
+
```
|
|
3114
|
+
|
|
3115
|
+
- ### Using Skyflow ID's or Unique Column Values
|
|
3116
|
+
You can retrieve data from the vault with the `get(records, options)` method using either Skyflow IDs or unique column values.
|
|
3117
|
+
|
|
3118
|
+
The records parameter accepts a JSON object that contains an array of either Skyflow IDs or unique column names and values.
|
|
3119
|
+
|
|
3120
|
+
The options is an optional `IGetOptions` object that retrieves the tokens for SkyflowIDs.
|
|
3121
|
+
|
|
3122
|
+
Notes:
|
|
3123
|
+
|
|
3124
|
+
- You can use either Skyflow IDs or unique values to retrieve records. You can't use both at the same time.
|
|
3125
|
+
- `options` parameter is applicable only for retrieving tokens using Skyflow ID.
|
|
3126
|
+
- You can't pass options along with the redaction type.
|
|
3127
|
+
- `tokens` defaults to false.
|
|
3128
|
+
|
|
3129
|
+
Skyflow.RedactionTypes accepts four values:
|
|
3130
|
+
- `PLAIN_TEXT`
|
|
3131
|
+
- `MASKED`
|
|
3132
|
+
- `REDACTED`
|
|
3133
|
+
- `DEFAULT`
|
|
3134
|
+
|
|
3135
|
+
You must apply a redaction type to retrieve data.
|
|
3136
|
+
|
|
3137
|
+
#### Schema (Skyflow IDs)
|
|
3138
|
+
|
|
3139
|
+
```javascript
|
|
3140
|
+
data = {
|
|
3141
|
+
records: [
|
|
3142
|
+
{
|
|
3143
|
+
ids: ["SKYFLOW_ID_1", "SKYFLOW_ID_2"], // List of skyflow_ids for the records to fetch.
|
|
3144
|
+
table: "NAME_OF_SKYFLOW_TABLE", // Name of table holding the records in the vault.
|
|
3145
|
+
redaction: Skyflow.RedactionType, // Redaction type to apply to retrieved data.
|
|
3146
|
+
},
|
|
3147
|
+
],
|
|
3148
|
+
};
|
|
3149
|
+
```
|
|
3150
|
+
#### Schema (Unique column values)
|
|
3151
|
+
|
|
3152
|
+
```javascript
|
|
3153
|
+
data = {
|
|
3154
|
+
records: [
|
|
3155
|
+
{
|
|
3156
|
+
table: "NAME_OF_SKYFLOW_TABLE", // Name of table holding the records in the vault.
|
|
3157
|
+
columnName: "UNIQUE_COLUMN_NAME", // Unique column name in the vault.
|
|
3158
|
+
columnValues: [ // List of given unique column values.
|
|
3159
|
+
"<COLUMN_VALUE_2>",
|
|
3160
|
+
"<COLUMN_VALUE_3>",
|
|
3161
|
+
], // Required when specifying a unique column
|
|
3162
|
+
redaction: Skyflow.RedactionType, // Redaction type applies to retrieved data.
|
|
3163
|
+
|
|
3164
|
+
},
|
|
3165
|
+
],
|
|
3166
|
+
};
|
|
3167
|
+
```
|
|
3168
|
+
[Example usage (Skyflow IDs)](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/get-pure-js.html)
|
|
3169
|
+
|
|
3170
|
+
```javascript
|
|
3171
|
+
skyflow.get({
|
|
3172
|
+
records: [
|
|
3173
|
+
{
|
|
3174
|
+
ids: ["f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9"],
|
|
3175
|
+
table: "cards",
|
|
3176
|
+
redaction: Skyflow.RedactionType.PLAIN_TEXT,
|
|
3177
|
+
},
|
|
3178
|
+
{
|
|
3179
|
+
ids: ["da26de53-95d5-4bdb-99db-8d8c66a35ff9"],
|
|
3180
|
+
table: "contacts",
|
|
3181
|
+
redaction: Skyflow.RedactionType.PLAIN_TEXT,
|
|
3182
|
+
},
|
|
3183
|
+
],
|
|
3184
|
+
});
|
|
3185
|
+
```
|
|
3186
|
+
Example response
|
|
3187
|
+
|
|
3188
|
+
```javascript
|
|
3189
|
+
{
|
|
3190
|
+
"records": [
|
|
3191
|
+
{
|
|
3192
|
+
"fields": {
|
|
3193
|
+
"card_number": "4111111111111111",
|
|
3194
|
+
"cvv": "127",
|
|
3195
|
+
"expiry_date": "11/2035",
|
|
3196
|
+
"fullname": "myname",
|
|
3197
|
+
"id": "f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9"
|
|
3198
|
+
},
|
|
3199
|
+
"table": "cards"
|
|
3200
|
+
}
|
|
3201
|
+
],
|
|
3202
|
+
"errors": [
|
|
3203
|
+
{
|
|
3204
|
+
"error": {
|
|
3205
|
+
"code": "404",
|
|
3206
|
+
"description": "No Records Found"
|
|
3207
|
+
},
|
|
3208
|
+
"ids": ["da26de53-95d5-4bdb-99db-8d8c66a35ff9"]
|
|
3209
|
+
}
|
|
3210
|
+
]
|
|
3211
|
+
}
|
|
3212
|
+
```
|
|
3213
|
+
[Example usage (Unique column values)](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/get-pure-js.html)
|
|
3214
|
+
|
|
3215
|
+
```javascript
|
|
3216
|
+
skyflow.get({
|
|
3217
|
+
records: [
|
|
3218
|
+
{
|
|
3219
|
+
table: "cards",
|
|
3220
|
+
redaction: RedactionType.PLAIN_TEXT,
|
|
3221
|
+
columnName: "card_id",
|
|
3222
|
+
columnValues: ["123", "456"],
|
|
3223
|
+
}
|
|
3224
|
+
],
|
|
3225
|
+
});
|
|
3226
|
+
```
|
|
3227
|
+
Sample response:
|
|
3228
|
+
```javascript
|
|
3229
|
+
{
|
|
3230
|
+
"records": [
|
|
3231
|
+
{
|
|
3232
|
+
"fields": {
|
|
3233
|
+
"card_id": "123",
|
|
3234
|
+
"expiry_date": "11/35",
|
|
3235
|
+
"fullname": "myname",
|
|
3236
|
+
"id": "f8d2-b557-4c6b-a12c-c5ebfd9"
|
|
3237
|
+
},
|
|
3238
|
+
"table": "cards"
|
|
3239
|
+
},
|
|
3240
|
+
{
|
|
3241
|
+
"fields": {
|
|
3242
|
+
"card_id": "456",
|
|
3243
|
+
"expiry_date": "10/23",
|
|
3244
|
+
"fullname": "sam",
|
|
3245
|
+
"id": "da53-95d5-4bdb-99db-8d8c5ff9"
|
|
3246
|
+
},
|
|
3247
|
+
"table": "cards"
|
|
3248
|
+
}
|
|
3249
|
+
]
|
|
3250
|
+
}
|
|
3251
|
+
```
|
|
3252
|
+
|
|
3253
|
+
[Example usage (Fetch tokens using Skyflow IDs)](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/get-pure-js.html)
|
|
3254
|
+
```javascript
|
|
3255
|
+
skyflow.get({
|
|
3256
|
+
records: [
|
|
3257
|
+
{
|
|
3258
|
+
ids: [
|
|
3259
|
+
"f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9",
|
|
3260
|
+
"da26de53-95d5-4bdb-99db-8d8c66a35ff9"
|
|
3261
|
+
],
|
|
3262
|
+
table: "cards",
|
|
3263
|
+
},
|
|
3264
|
+
],
|
|
3265
|
+
}, { tokens: true });
|
|
3266
|
+
```
|
|
3267
|
+
Sample response:
|
|
3268
|
+
```javascript
|
|
3269
|
+
{
|
|
3270
|
+
"records": [
|
|
3271
|
+
{
|
|
3272
|
+
"fields": {
|
|
3273
|
+
"card_id": "f689e421-4cf8-4438-8dbd-cc8e7654b7d9",
|
|
3274
|
+
"expiry_date": "d9ef1cb8-5c22-48b0-b769-64ac20ccee01",
|
|
3275
|
+
"fullname": "37480f82-d237-4efc-a06a-ebe57121be06",
|
|
3276
|
+
"id": "f8d2-b557-4c6b-a12c-c5ebfd9"
|
|
3277
|
+
},
|
|
3278
|
+
"table": "cards"
|
|
3279
|
+
},
|
|
3280
|
+
{
|
|
3281
|
+
"fields": {
|
|
3282
|
+
"card_id": "d794b64c-e283-4fb8-8eef-9f6710730b69",
|
|
3283
|
+
"expiry_date": "ff848fc3-a093-4ed4-9414-877b74a33111",
|
|
3284
|
+
"fullname": "dfb6c247-3ee6-4fd2-8d1e-19d8e11c25ce",
|
|
3285
|
+
"id": "da53-95d5-4bdb-99db-8d8c5ff9"
|
|
3286
|
+
},
|
|
3287
|
+
"table": "cards"
|
|
3288
|
+
}
|
|
3289
|
+
]
|
|
3290
|
+
}
|
|
3291
|
+
```
|
|
3292
|
+
|
|
3293
|
+
## Using Skyflow Elements to reveal data
|
|
3294
|
+
|
|
3295
|
+
Skyflow Elements can be used to securely reveal data in a browser without exposing your front end to the sensitive data. This is great for use cases like card issuance where you may want to reveal the card number to a user without increasing your PCI compliance scope.
|
|
3296
|
+
|
|
3297
|
+
### Step 1: Create a container
|
|
3298
|
+
To start, create a container using the `container(Skyflow.ContainerType)` method of the Skyflow client as shown below.
|
|
3299
|
+
|
|
3300
|
+
```javascript
|
|
3301
|
+
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL)
|
|
3302
|
+
```
|
|
3303
|
+
|
|
3304
|
+
### Step 2: Create a reveal Element
|
|
3305
|
+
|
|
3306
|
+
Then define a Skyflow Element to reveal data as shown below.
|
|
3307
|
+
|
|
3308
|
+
```javascript
|
|
3309
|
+
const revealElement = {
|
|
3310
|
+
token: 'string', // Required, token of the data being revealed.
|
|
3311
|
+
inputStyles: {}, // Optional, styles to be applied to the element.
|
|
3312
|
+
labelStyles: {}, // Optional, styles to be applied to the label of the reveal element.
|
|
3313
|
+
errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the reveal element.
|
|
3314
|
+
label: 'string', // Optional, label for the form element.
|
|
3315
|
+
altText: 'string', // Optional, string that is shown before reveal, will show token if altText is not provided.
|
|
3316
|
+
redaction: RedactionType, //Optional, Redaction Type to be applied to data, RedactionType.PLAIN_TEXT will be applied if not provided.
|
|
3317
|
+
};
|
|
3318
|
+
```
|
|
3319
|
+
|
|
3320
|
+
Note: If you don't provide a redaction type, RedactionType.PLAIN_TEXT will apply by default.
|
|
3321
|
+
|
|
3322
|
+
The `inputStyles`, `labelStyles` and `errorTextStyles` parameters accepts a styles object as described in the [previous section](#step-2-create-a-collect-element) for collecting data. But for reveal element, `inputStyles` accepts only `base` variant, `copyIcon` and `global` style objects.
|
|
3323
|
+
|
|
3324
|
+
An example of a inputStyles object:
|
|
3325
|
+
|
|
3326
|
+
```javascript
|
|
3327
|
+
inputStyles: {
|
|
3328
|
+
base: {
|
|
3329
|
+
color: '#1d1d1d',
|
|
3330
|
+
},
|
|
3331
|
+
copyIcon: {
|
|
3332
|
+
position: 'absolute',
|
|
3333
|
+
right: '8px',
|
|
3334
|
+
top: 'calc(50% - 10px)',
|
|
3335
|
+
},
|
|
3336
|
+
global: {
|
|
3337
|
+
'@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
|
|
3338
|
+
}
|
|
3339
|
+
},
|
|
3340
|
+
```
|
|
3341
|
+
|
|
3342
|
+
An example of a labelStyles object:
|
|
3343
|
+
|
|
3344
|
+
```javascript
|
|
3345
|
+
labelStyles: {
|
|
3346
|
+
base: {
|
|
3347
|
+
fontSize: '12px',
|
|
3348
|
+
fontWeight: 'bold',
|
|
3349
|
+
},
|
|
3350
|
+
global: {
|
|
3351
|
+
'@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
|
|
3352
|
+
}
|
|
3353
|
+
},
|
|
3354
|
+
```
|
|
3355
|
+
|
|
3356
|
+
An example of a errorTextStyles object:
|
|
3357
|
+
|
|
3358
|
+
```javascript
|
|
3359
|
+
errorTextStyles: {
|
|
3360
|
+
base: {
|
|
3361
|
+
color: '#f44336',
|
|
3362
|
+
},
|
|
3363
|
+
global: {
|
|
3364
|
+
'@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
|
|
3365
|
+
}
|
|
3366
|
+
},
|
|
3367
|
+
```
|
|
3368
|
+
|
|
3369
|
+
Along with RevealElementInput, you can define other options in the RevealElementOptions object as described below:
|
|
3370
|
+
```js
|
|
3371
|
+
const options = {
|
|
3372
|
+
enableCopy: false, // Optional, enables the copy icon to reveal elements to copy text to clipboard. Defaults to 'false').
|
|
3373
|
+
format: String, // Optional, format for the element
|
|
3374
|
+
translation: {} // Optional, indicates the allowed data type value for format.
|
|
3375
|
+
}
|
|
3376
|
+
```
|
|
3377
|
+
|
|
3378
|
+
`format`: A string value that indicates how the reveal element should display the value, including placeholder characters that map to keys `translation` If `translation` isn't specified to any character in the `format` value is considered as a string literal.
|
|
3379
|
+
|
|
3380
|
+
`translation`: An object of key value pairs, where the key is a character that appears in `format` and the value is a simple regex pattern of acceptable inputs for that character. Each key can only appear once. Defaults to `{ ‘X’: ‘[0-9]’ }`.
|
|
3381
|
+
|
|
3382
|
+
**Reveal Element Options examples:**
|
|
3383
|
+
Example 1
|
|
3384
|
+
```js
|
|
3385
|
+
const revealElementInput = {
|
|
3386
|
+
token: '<token>'
|
|
3387
|
+
};
|
|
3388
|
+
|
|
3389
|
+
const options = {
|
|
3390
|
+
format: '(XXX) XXX-XXXX',
|
|
3391
|
+
translation: { 'X': '[0-9]'}
|
|
3392
|
+
};
|
|
3393
|
+
|
|
3394
|
+
const revealElement = revealContainer.create(revealElementInput,options);
|
|
3395
|
+
```
|
|
3396
|
+
|
|
3397
|
+
Value from vault: "1234121234"
|
|
3398
|
+
Revealed Value displayed in element: "(123) 412-1234"
|
|
3399
|
+
|
|
3400
|
+
Example 2:
|
|
3401
|
+
```js
|
|
3402
|
+
const revealElementInput = {
|
|
3403
|
+
token: '<token>'
|
|
3404
|
+
};
|
|
3405
|
+
|
|
3406
|
+
const options = {
|
|
3407
|
+
format: 'XXXX-XXXXXX-XXXXX',
|
|
3408
|
+
translation: { 'X': '[0-9]' }
|
|
3409
|
+
};
|
|
3410
|
+
|
|
3411
|
+
const revealElement = revealContainer.create(revealElementInput,options);
|
|
3412
|
+
```
|
|
3413
|
+
|
|
3414
|
+
Value from vault: "374200000000004"
|
|
3415
|
+
Revealed Value displayed in element: "3742-000000-00004"
|
|
3416
|
+
|
|
3417
|
+
Once you've defined a Skyflow Element, you can use the `create(element)` method of the container to create the Element as shown below:
|
|
3418
|
+
|
|
3419
|
+
```javascript
|
|
3420
|
+
const element = container.create(revealElement)
|
|
3421
|
+
```
|
|
3422
|
+
|
|
3423
|
+
### Step 3: Mount Elements to the DOM
|
|
3424
|
+
|
|
3425
|
+
Elements used for revealing data are mounted to the DOM the same way as Elements used for collecting data. Refer to Step 3 of the [section above](#step-3-mount-elements-to-the-dom).
|
|
3426
|
+
|
|
3427
|
+
|
|
3428
|
+
### Step 4: Reveal data
|
|
3429
|
+
When the sensitive data is ready to be retrieved and revealed, call the `reveal()` method on the container as shown below:
|
|
3430
|
+
|
|
3431
|
+
```javascript
|
|
3432
|
+
container
|
|
3433
|
+
.reveal()
|
|
3434
|
+
.then(data => {
|
|
3435
|
+
// Handle success.
|
|
3436
|
+
})
|
|
3437
|
+
.catch(err => {
|
|
3438
|
+
// Handle error.
|
|
3439
|
+
});
|
|
3440
|
+
```
|
|
3441
|
+
|
|
3442
|
+
|
|
3443
|
+
### End to end example of all steps
|
|
3444
|
+
|
|
3445
|
+
**[Sample Code:](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/skyflow-elements.html)**
|
|
3446
|
+
```javascript
|
|
3447
|
+
// Step 1.
|
|
3448
|
+
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
|
|
3449
|
+
|
|
3450
|
+
// Step 2.
|
|
3451
|
+
const cardNumberElement = container.create({
|
|
3452
|
+
token: 'b63ec4e0-bbad-4e43-96e6-6bd50f483f75',
|
|
3453
|
+
inputStyles: {
|
|
3454
|
+
base: {
|
|
3455
|
+
color: '#1d1d1d',
|
|
3456
|
+
},
|
|
3457
|
+
},
|
|
3458
|
+
labelStyles: {
|
|
3459
|
+
base: {
|
|
3460
|
+
fontSize: '12px',
|
|
3461
|
+
},
|
|
3462
|
+
},
|
|
3463
|
+
errorTextStyles: {
|
|
3464
|
+
base: {
|
|
3465
|
+
color: '#f44336',
|
|
3466
|
+
},
|
|
3467
|
+
},
|
|
3468
|
+
label: 'card_number',
|
|
3469
|
+
altText: 'XXXX XXXX XXXX XXXX',
|
|
3470
|
+
redaction: Skyflow.RedactionType.MASKED
|
|
3471
|
+
});
|
|
3472
|
+
|
|
3473
|
+
const cvvElement = container.create({
|
|
3474
|
+
token: '89024714-6a26-4256-b9d4-55ad69aa4047',
|
|
3475
|
+
inputStyles: {
|
|
3476
|
+
base: {
|
|
3477
|
+
color: '#1d1d1d',
|
|
3478
|
+
},
|
|
3479
|
+
},
|
|
3480
|
+
label: 'cvv',
|
|
3481
|
+
altText: 'XXX',
|
|
3482
|
+
});
|
|
3483
|
+
|
|
3484
|
+
const expiryDate= container.create({
|
|
3485
|
+
token: 'a4b24714-6a26-4256-b9d4-55ad69aa4047',
|
|
3486
|
+
inputStyles: {
|
|
3487
|
+
base: {
|
|
3488
|
+
color: '#1d1d1d',
|
|
3489
|
+
},
|
|
3490
|
+
},
|
|
3491
|
+
label: 'expiryDate',
|
|
3492
|
+
altText: 'MM/YYYY',
|
|
3493
|
+
});
|
|
3494
|
+
// Step 3.
|
|
3495
|
+
cardNumberElement.mount('#cardNumber'); // Assumes there is a placeholder div with id='cardNumber' on the page
|
|
3496
|
+
cvvElement.mount('#cvv'); // Assumes there is a placeholder div with id='cvv' on the page
|
|
3497
|
+
expiryDate.mount('#expiryDate'); // Assumes there is a placeholder div with id='expiryDate' on the page
|
|
3498
|
+
|
|
3499
|
+
// Step 4.
|
|
3500
|
+
container
|
|
3501
|
+
.reveal()
|
|
3502
|
+
.then(data => {
|
|
3503
|
+
// Handle success.
|
|
3504
|
+
})
|
|
3505
|
+
.catch(err => {
|
|
3506
|
+
// Handle error.
|
|
3507
|
+
});
|
|
3508
|
+
```
|
|
3509
|
+
|
|
3510
|
+
The response below shows that some tokens assigned to the reveal elements get revealed successfully, while others fail and remain unrevealed.
|
|
3511
|
+
|
|
3512
|
+
### Sample Response
|
|
3513
|
+
|
|
3514
|
+
```
|
|
3515
|
+
{
|
|
3516
|
+
"success": [
|
|
3517
|
+
{
|
|
3518
|
+
"token": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
|
|
3519
|
+
"value": "xxxxxxxxx4163"
|
|
3520
|
+
"valueType": "STRING"
|
|
3521
|
+
},
|
|
3522
|
+
{
|
|
3523
|
+
"token": "a4b24714-6a26-4256-b9d4-55ad69aa4047",
|
|
3524
|
+
"value": "12/2098"
|
|
3525
|
+
"valueType": "STRING"
|
|
3526
|
+
}
|
|
3527
|
+
],
|
|
3528
|
+
"errors": [
|
|
3529
|
+
{
|
|
3530
|
+
"token": "89024714-6a26-4256-b9d4-55ad69aa4047",
|
|
3531
|
+
"error": {
|
|
3532
|
+
"code": 404,
|
|
3533
|
+
"description": "Tokens not found for 89024714-6a26-4256-b9d4-55ad69aa4047"
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
]
|
|
3537
|
+
}
|
|
3538
|
+
```
|
|
3539
|
+
|
|
3540
|
+
### UI Error for Reveal Elements
|
|
3541
|
+
Helps to display custom error messages on the Skyflow Elements through the methods `setError` and `resetError` on the elements.
|
|
3542
|
+
|
|
3543
|
+
`setError(error: string)` method is used to set the error text for the element, when this method is triggered, all the current errors present on the element will be overridden with the custom error message passed. This error will be displayed on the element until `resetError()` is triggered on the same element.
|
|
3544
|
+
|
|
3545
|
+
`resetError()` method is used to clear the custom error message that is set using `setError`.
|
|
3546
|
+
|
|
3547
|
+
##### Sample code snippet for setError and resetError
|
|
3548
|
+
|
|
3549
|
+
```javascript
|
|
3550
|
+
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
|
|
3551
|
+
|
|
3552
|
+
const cardNumber = container.create({
|
|
3553
|
+
token: '89024714-6a26-4256-b9d4-55ad69aa4047',
|
|
3554
|
+
});
|
|
3555
|
+
|
|
3556
|
+
// Set custom error.
|
|
3557
|
+
cardNumber.setError('custom error');
|
|
3558
|
+
|
|
3559
|
+
// Reset custom error.
|
|
3560
|
+
cardNumber.resetError();
|
|
3561
|
+
```
|
|
3562
|
+
|
|
3563
|
+
### Override default error messages
|
|
3564
|
+
|
|
3565
|
+
You can override the default error messages with custom ones by using `setErrorOverride`. This is especially useful to override default error messages in non-English languages.
|
|
3566
|
+
|
|
3567
|
+
```javascript
|
|
3568
|
+
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
|
|
3569
|
+
|
|
3570
|
+
const cardNumber = container.create({
|
|
3571
|
+
token: '89024714-6a26-4256-b9d4-55ad69aa4047',
|
|
3572
|
+
});
|
|
3573
|
+
|
|
3574
|
+
const revealButton = document.getElementById('revealPCIData');
|
|
3575
|
+
|
|
3576
|
+
if (revealButton) {
|
|
3577
|
+
revealButton.addEventListener('click', () => {
|
|
3578
|
+
revealContainer.reveal().then((res) => {
|
|
3579
|
+
//handle reveal response
|
|
3580
|
+
}).catch((err) => {
|
|
3581
|
+
cardNumber.setErrorOverride("custom error")
|
|
3582
|
+
});
|
|
3583
|
+
});
|
|
3584
|
+
}
|
|
3585
|
+
```
|
|
3586
|
+
|
|
3587
|
+
### Set token for Reveal Elements
|
|
3588
|
+
|
|
3589
|
+
The `setToken(value: string)` method can be used to set the token of the Reveal Element. If no altText is set, the set token will be displayed on the UI as well. If altText is set, then there will be no change in the UI but the token of the element will be internally updated.
|
|
3590
|
+
|
|
3591
|
+
##### Sample code snippet for setToken
|
|
3592
|
+
```javascript
|
|
3593
|
+
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
|
|
3594
|
+
|
|
3595
|
+
const cardNumber = container.create({
|
|
3596
|
+
altText: 'Card Number',
|
|
3597
|
+
});
|
|
3598
|
+
|
|
3599
|
+
// Set token.
|
|
3600
|
+
cardNumber.setToken('89024714-6a26-4256-b9d4-55ad69aa4047');
|
|
3601
|
+
```
|
|
3602
|
+
### Set and Clear altText for Reveal Elements
|
|
3603
|
+
The `setAltText(value: string)` method can be used to set the altText of the Reveal Element. This will cause the altText to be displayed in the UI regardless of whether the token or value is currently being displayed.
|
|
3604
|
+
|
|
3605
|
+
`clearAltText()` method can be used to clear the altText, this will cause the element to display the token or actual value of the element. If the element has no token, the element will be empty.
|
|
3606
|
+
##### Sample code snippet for setAltText and clearAltText
|
|
3607
|
+
|
|
3608
|
+
```javascript
|
|
3609
|
+
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
|
|
3610
|
+
|
|
3611
|
+
const cardNumber = container.create({
|
|
3612
|
+
token: '89024714-6a26-4256-b9d4-55ad69aa4047',
|
|
3613
|
+
});
|
|
3614
|
+
|
|
3615
|
+
// Set altText.
|
|
3616
|
+
cardNumber.setAltText('Card Number');
|
|
3617
|
+
|
|
3618
|
+
// Clear altText.
|
|
3619
|
+
cardNumber.clearAltText();
|
|
3620
|
+
|
|
3621
|
+
```
|
|
3622
|
+
|
|
3623
|
+
## Render a file with a File Element
|
|
3624
|
+
|
|
3625
|
+
You can render files using the Skyflow File Element. Use the following steps to securely render a file.
|
|
3626
|
+
|
|
3627
|
+
### Step 1: Create a container
|
|
3628
|
+
Create a container for the form elements using the container(Skyflow.ContainerType) method of the Skyflow client:
|
|
3629
|
+
|
|
3630
|
+
```javascript
|
|
3631
|
+
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL)
|
|
3632
|
+
```
|
|
3633
|
+
|
|
3634
|
+
### Step 2: Create a File Element
|
|
3635
|
+
Define a Skyflow Element to render the file as shown below.
|
|
3636
|
+
|
|
3637
|
+
```javascript
|
|
3638
|
+
const fileElement = {
|
|
3639
|
+
inputStyles: {}, // Optional, styles to be applied to the element.
|
|
3640
|
+
errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the render element.
|
|
3641
|
+
altText: 'string', // Optional, string that is shown before file render call
|
|
3642
|
+
skyflowID: 'string', // Required, skyflow id of the file to render
|
|
3643
|
+
column: 'string', // Required, column name of the file to render
|
|
3644
|
+
table: 'string', // Required, table name of the file to render
|
|
3645
|
+
};
|
|
3646
|
+
```
|
|
3647
|
+
The inputStyles and errorTextStyles parameters accept a styles object as described in the [previous section](https://github.com/skyflowapi/skyflow-js#step-2-create-a-collect-element) for collecting data. But for render file elements, inputStyles accepts only base variant, global style objects.
|
|
3648
|
+
|
|
3649
|
+
An example of a inputStyles object:
|
|
3650
|
+
|
|
3651
|
+
```javascript
|
|
3652
|
+
inputStyles: {
|
|
3653
|
+
base: {
|
|
3654
|
+
height: '400px',
|
|
3655
|
+
width: '300px',
|
|
3656
|
+
},
|
|
3657
|
+
global: {
|
|
3658
|
+
'@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
|
|
3659
|
+
}
|
|
3660
|
+
}
|
|
3661
|
+
```
|
|
3662
|
+
An example of a errorTextStyles object:
|
|
3663
|
+
```javascript
|
|
3664
|
+
errorTextStyles: {
|
|
3665
|
+
base: {
|
|
3666
|
+
color: '#f44336',
|
|
3667
|
+
},
|
|
3668
|
+
global: {
|
|
3669
|
+
'@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
|
|
3670
|
+
}
|
|
3671
|
+
}
|
|
3672
|
+
```
|
|
3673
|
+
|
|
3674
|
+
### Step 3: Mount Elements to the DOM
|
|
3675
|
+
Elements used for rendering files are mounted to the DOM the same way as Elements used for collecting data. Refer to Step 3 of the [section above](https://github.com/skyflowapi/skyflow-js#step-3-mount-elements-to-the-dom).
|
|
3676
|
+
|
|
3677
|
+
### Step 4: Render File
|
|
3678
|
+
After you create and mount the element, call the `renderFile()` method on the element as shown below:
|
|
3679
|
+
```javascript
|
|
3680
|
+
fileElement
|
|
3681
|
+
.renderFile()
|
|
3682
|
+
.then(data => {
|
|
3683
|
+
// Handle success.
|
|
3684
|
+
})
|
|
3685
|
+
.catch(err => {
|
|
3686
|
+
// Handle error.
|
|
3687
|
+
});
|
|
3688
|
+
```
|
|
3689
|
+
|
|
3690
|
+
### End to end example of file render
|
|
3691
|
+
```javascript
|
|
3692
|
+
// Step 1.
|
|
3693
|
+
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
|
|
3694
|
+
|
|
3695
|
+
// REPLACE with your custom implementation to fetch skyflow_id from backend service.
|
|
3696
|
+
// Sample implementation
|
|
3697
|
+
fetch("<BACKEND_URL>")
|
|
3698
|
+
.then((response) => {
|
|
3699
|
+
|
|
3700
|
+
// on successful fetch skyflow_id
|
|
3701
|
+
const skyflowID = response.skyflow_id;
|
|
3702
|
+
|
|
3703
|
+
// Step 2.
|
|
3704
|
+
const fileElement = container.create({
|
|
3705
|
+
skyflowID: "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
|
|
3706
|
+
column: "file",
|
|
3707
|
+
table: "table",
|
|
3708
|
+
inputStyles: {
|
|
3709
|
+
base: {
|
|
3710
|
+
height: "400px",
|
|
3711
|
+
width: "300px",
|
|
3712
|
+
},
|
|
3713
|
+
},
|
|
3714
|
+
errorTextStyles: {
|
|
3715
|
+
base: {
|
|
3716
|
+
color: "#f44336",
|
|
3717
|
+
},
|
|
3718
|
+
},
|
|
3719
|
+
altText: "This is an altText",
|
|
3720
|
+
});
|
|
3721
|
+
// Step 3.
|
|
3722
|
+
fileElement.mount("#renderFile"); // Assumes there is a placeholder div with id=renderFile on the page
|
|
3723
|
+
|
|
3724
|
+
const renderButton = document.getElementById("renderFiles"); // button to call render file
|
|
3725
|
+
|
|
3726
|
+
if (renderButton) {
|
|
3727
|
+
renderButton.addEventListener("click", () => {
|
|
3728
|
+
|
|
3729
|
+
// Step 4.
|
|
3730
|
+
fileElement
|
|
3731
|
+
.renderFile()
|
|
3732
|
+
.then((data) => {
|
|
3733
|
+
// Handle success.
|
|
3734
|
+
})
|
|
3735
|
+
.catch((err) => {
|
|
3736
|
+
// Handle error.
|
|
3737
|
+
});
|
|
3738
|
+
});
|
|
3739
|
+
}
|
|
3740
|
+
})
|
|
3741
|
+
.catch((err) => {
|
|
3742
|
+
// failed to fetch skyflow_id
|
|
3743
|
+
console.log(err);
|
|
3744
|
+
});
|
|
3745
|
+
|
|
3746
|
+
```
|
|
3747
|
+
|
|
3748
|
+
### Sample Success Response
|
|
3749
|
+
```json
|
|
3750
|
+
{
|
|
3751
|
+
"success": [
|
|
3752
|
+
{
|
|
3753
|
+
"skyflow_id": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
|
|
3754
|
+
"column": "file"
|
|
3755
|
+
},
|
|
3756
|
+
]
|
|
3757
|
+
}
|
|
3758
|
+
```
|
|
3759
|
+
|
|
3760
|
+
## Update Reveal Elements
|
|
3761
|
+
|
|
3762
|
+
You can update reveal element properties with the `update` interface.
|
|
3763
|
+
|
|
3764
|
+
The `update` interface takes the below object:
|
|
3765
|
+
```javascript
|
|
3766
|
+
const updateElement = {
|
|
3767
|
+
token: 'string', // Optional, token of the data being revealed.
|
|
3768
|
+
inputStyles: {}, // Optional, styles to be applied to the element.
|
|
3769
|
+
labelStyles: {}, // Optional, styles to be applied to the label of the reveal element.
|
|
3770
|
+
errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the reveal element.
|
|
3771
|
+
label: 'string', // Optional, label for the form element.
|
|
3772
|
+
altText: 'string', // Optional, string that is shown before reveal, will show token if altText is not provided.
|
|
3773
|
+
redaction: RedactionType, // Optional, Redaction Type to be applied to data.
|
|
3774
|
+
skyflowID: 'string', // Optional, Skyflow ID of the file to render.
|
|
3775
|
+
table: 'string', // Optional, table name of the file to render.
|
|
3776
|
+
column: 'string' // Optional, column name of the file to render.
|
|
3777
|
+
};
|
|
3778
|
+
```
|
|
3779
|
+
|
|
3780
|
+
Only include the properties that you want to update for the specified reveal element.
|
|
3781
|
+
|
|
3782
|
+
Properties your provided when you created the element remain the same until you explicitly update them.
|
|
3783
|
+
|
|
3784
|
+
### End to end example
|
|
3785
|
+
```javascript
|
|
3786
|
+
// Create a reveal container.
|
|
3787
|
+
const revealContainer = skyflowClient.container(Skyflow.ContainerType.REVEAL);
|
|
3788
|
+
|
|
3789
|
+
const stylesOptions = {
|
|
3790
|
+
inputStyles: {
|
|
3791
|
+
base: {
|
|
3792
|
+
fontFamily: 'Inter',
|
|
3793
|
+
fontStyle: 'normal',
|
|
3794
|
+
fontWeight: 400,
|
|
3795
|
+
fontSize: '14px',
|
|
3796
|
+
lineHeight: '21px',
|
|
3797
|
+
width: '294px',
|
|
3798
|
+
},
|
|
3799
|
+
},
|
|
3800
|
+
labelStyles: {},
|
|
3801
|
+
errorTextStyles: {
|
|
3802
|
+
base: {
|
|
3803
|
+
color: '#f44336'
|
|
3804
|
+
},
|
|
3805
|
+
},
|
|
3806
|
+
};
|
|
3807
|
+
|
|
3808
|
+
// Create reveal elements
|
|
3809
|
+
const cardHolderNameRevealElement = revealContainer.create({
|
|
3810
|
+
token: 'ed5fdd1f-5009-435c-a06b-3417ce76d2c8',
|
|
3811
|
+
altText: 'first name',
|
|
3812
|
+
...stylesOptions,
|
|
3813
|
+
label: 'Card Holder Name',
|
|
3814
|
+
});
|
|
3815
|
+
|
|
3816
|
+
const cardNumberRevealElement = revealContainer.create({
|
|
3817
|
+
token: '8ee84061-7107-4faf-bb25-e044f3d191fe',
|
|
3818
|
+
altText: 'xxxx',
|
|
3819
|
+
...stylesOptions,
|
|
3820
|
+
label: 'Card Number',
|
|
3821
|
+
redaction: 'RedactionType.CARD_NUMBER'
|
|
3822
|
+
});
|
|
3823
|
+
|
|
3824
|
+
// Mount the reveal elements.
|
|
3825
|
+
cardHolderNameRevealElement.mount('#cardHolderNameRevealElement'); // Assumes there is a div with id='#cardHolderNameRevealElement' in the webpage.
|
|
3826
|
+
cardNumberRevealElement.mount('#cardNumberRevealElement'); // Assumes there is a div with id='#cardNumberRevealElement' in the webpage.
|
|
3827
|
+
|
|
3828
|
+
// ...
|
|
3829
|
+
|
|
3830
|
+
// Update label, labelStyles properties on cardHolderNameRevealElement.
|
|
3831
|
+
cardHolderNameRevealElement.update({
|
|
3832
|
+
label: 'CARDHOLDER NAME',
|
|
3833
|
+
labelStyles: {
|
|
3834
|
+
base: {
|
|
3835
|
+
color: '#aa11aa'
|
|
3836
|
+
}
|
|
3837
|
+
}
|
|
3838
|
+
});
|
|
3839
|
+
|
|
3840
|
+
// Update inputStyles, errorTextStyles properties on cardNumberRevealElement.
|
|
3841
|
+
cardNumberRevealElement.update({
|
|
3842
|
+
inputStyles: {
|
|
3843
|
+
base: {
|
|
3844
|
+
color: '#fff',
|
|
3845
|
+
backgroundColor: '#000',
|
|
3846
|
+
borderColor: '#f00',
|
|
3847
|
+
borderWidth: '5px'
|
|
3848
|
+
}
|
|
3849
|
+
},
|
|
3850
|
+
errorTextStyles: {
|
|
3851
|
+
base: {
|
|
3852
|
+
backgroundColor: '#000',
|
|
3853
|
+
}
|
|
3854
|
+
}
|
|
3855
|
+
});
|
|
3856
|
+
```
|
|
3857
|
+
|
|
3858
|
+
---
|
|
3859
|
+
|
|
3860
|
+
|
|
3861
|
+
## Using Composable Reveal Elements to reveal data
|
|
3862
|
+
|
|
3863
|
+
Composable Reveal Elements combine multiple Skyflow Elements in a single iframe, letting you create multiple Skyflow Elements in a single row. The following steps create a composable reveal element and securely collect data through it.
|
|
3864
|
+
|
|
3865
|
+
### Step 1: Create a composable reveal container
|
|
3866
|
+
|
|
3867
|
+
Create a container for the composable reveal element using the `container(Skyflow.ContainerType)` method of the Skyflow client:
|
|
3868
|
+
|
|
3869
|
+
``` javascript
|
|
3870
|
+
const revealComposableContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSE_REVEAL, containerOptions);
|
|
3871
|
+
```
|
|
3872
|
+
Pass an options object that contains the following keys:
|
|
3873
|
+
|
|
3874
|
+
1. `layout`: An array that indicates the number of rows in the container and the number of elements in each row. The index value of the array defines the number of rows, and each value in the array represents the number of elements in that row, in order.
|
|
3875
|
+
|
|
3876
|
+
For example: `[2,1]` means the container has two rows, with two elements in the first row and one element in the second row.
|
|
3877
|
+
|
|
3878
|
+
`Note`: The sum of values in the layout array should be equal to the number of elements created
|
|
3879
|
+
|
|
3880
|
+
2. `styles`: CSS styles to apply to the reveal composable container.
|
|
3881
|
+
3. `errorTextStyles`: CSS styles to apply if an error is encountered.
|
|
3882
|
+
|
|
3883
|
+
```javascript
|
|
3884
|
+
const containerOptions = {
|
|
3885
|
+
layout: [2, 1], // Required
|
|
3886
|
+
styles: { // Optional
|
|
3887
|
+
base: {
|
|
3888
|
+
border: '1px solid #DFE3EB',
|
|
3889
|
+
padding: '8px',
|
|
3890
|
+
borderRadius: '4px',
|
|
3891
|
+
margin: '12px 2px',
|
|
3892
|
+
},
|
|
3893
|
+
},
|
|
3894
|
+
errorTextStyles: { // Optional
|
|
3895
|
+
base: {
|
|
3896
|
+
color: 'red',
|
|
3897
|
+
fontFamily: '"Roboto", sans-serif'
|
|
3898
|
+
},
|
|
3899
|
+
global: {
|
|
3900
|
+
'@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
|
|
3901
|
+
}
|
|
3902
|
+
},
|
|
3903
|
+
};
|
|
2382
3904
|
```
|
|
2383
3905
|
|
|
2384
|
-
### Step 2: Create
|
|
2385
|
-
|
|
2386
|
-
Then define a Skyflow Element to reveal data as shown below.
|
|
3906
|
+
### Step 2: Create Composable Reveal Elements
|
|
3907
|
+
Composable Reveal Elements use the following schema:
|
|
2387
3908
|
|
|
2388
3909
|
```javascript
|
|
2389
|
-
const
|
|
3910
|
+
const revealComposableElement = {
|
|
2390
3911
|
token: 'string', // Required, token of the data being revealed.
|
|
2391
3912
|
inputStyles: {}, // Optional, styles to be applied to the element.
|
|
2392
3913
|
labelStyles: {}, // Optional, styles to be applied to the label of the reveal element.
|
|
@@ -2396,7 +3917,6 @@ const revealElement = {
|
|
|
2396
3917
|
redaction: RedactionType, //Optional, Redaction Type to be applied to data, RedactionType.PLAIN_TEXT will be applied if not provided.
|
|
2397
3918
|
};
|
|
2398
3919
|
```
|
|
2399
|
-
|
|
2400
3920
|
Note: If you don't provide a redaction type, RedactionType.PLAIN_TEXT will apply by default.
|
|
2401
3921
|
|
|
2402
3922
|
The `inputStyles`, `labelStyles` and `errorTextStyles` parameters accepts a styles object as described in the [previous section](#step-2-create-a-collect-element) for collecting data. But for reveal element, `inputStyles` accepts only `base` variant, `copyIcon` and `global` style objects.
|
|
@@ -2470,319 +3990,75 @@ const options = {
|
|
|
2470
3990
|
format: '(XXX) XXX-XXXX',
|
|
2471
3991
|
translation: { 'X': '[0-9]'}
|
|
2472
3992
|
};
|
|
2473
|
-
|
|
2474
|
-
const revealElement =
|
|
2475
|
-
```
|
|
2476
|
-
|
|
2477
|
-
Value from vault: "1234121234"
|
|
2478
|
-
Revealed Value displayed in element: "(123) 412-1234"
|
|
2479
|
-
|
|
2480
|
-
Example 2:
|
|
2481
|
-
```js
|
|
2482
|
-
const revealElementInput = {
|
|
2483
|
-
token: '<token>'
|
|
2484
|
-
};
|
|
2485
|
-
|
|
2486
|
-
const options = {
|
|
2487
|
-
format: 'XXXX-XXXXXX-XXXXX',
|
|
2488
|
-
translation: { 'X': '[0-9]' }
|
|
2489
|
-
};
|
|
2490
|
-
|
|
2491
|
-
const revealElement = revealContainer.create(revealElementInput,options);
|
|
2492
|
-
```
|
|
2493
|
-
|
|
2494
|
-
Value from vault: "374200000000004"
|
|
2495
|
-
Revealed Value displayed in element: "3742-000000-00004"
|
|
2496
|
-
|
|
2497
|
-
Once you've defined a Skyflow Element, you can use the `create(element)` method of the container to create the Element as shown below:
|
|
2498
|
-
|
|
2499
|
-
```javascript
|
|
2500
|
-
const element = container.create(revealElement)
|
|
2501
|
-
```
|
|
2502
|
-
|
|
2503
|
-
### Step 3: Mount Elements to the DOM
|
|
2504
|
-
|
|
2505
|
-
Elements used for revealing data are mounted to the DOM the same way as Elements used for collecting data. Refer to Step 3 of the [section above](#step-3-mount-elements-to-the-dom).
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
### Step 4: Reveal data
|
|
2509
|
-
When the sensitive data is ready to be retrieved and revealed, call the `reveal()` method on the container as shown below:
|
|
2510
|
-
|
|
2511
|
-
```javascript
|
|
2512
|
-
container
|
|
2513
|
-
.reveal()
|
|
2514
|
-
.then(data => {
|
|
2515
|
-
// Handle success.
|
|
2516
|
-
})
|
|
2517
|
-
.catch(err => {
|
|
2518
|
-
// Handle error.
|
|
2519
|
-
});
|
|
2520
|
-
```
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
### End to end example of all steps
|
|
2524
|
-
|
|
2525
|
-
**[Sample Code:](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/skyflow-elements.html)**
|
|
2526
|
-
```javascript
|
|
2527
|
-
// Step 1.
|
|
2528
|
-
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
|
|
2529
|
-
|
|
2530
|
-
// Step 2.
|
|
2531
|
-
const cardNumberElement = container.create({
|
|
2532
|
-
token: 'b63ec4e0-bbad-4e43-96e6-6bd50f483f75',
|
|
2533
|
-
inputStyles: {
|
|
2534
|
-
base: {
|
|
2535
|
-
color: '#1d1d1d',
|
|
2536
|
-
},
|
|
2537
|
-
},
|
|
2538
|
-
labelStyles: {
|
|
2539
|
-
base: {
|
|
2540
|
-
fontSize: '12px',
|
|
2541
|
-
},
|
|
2542
|
-
},
|
|
2543
|
-
errorTextStyles: {
|
|
2544
|
-
base: {
|
|
2545
|
-
color: '#f44336',
|
|
2546
|
-
},
|
|
2547
|
-
},
|
|
2548
|
-
label: 'card_number',
|
|
2549
|
-
altText: 'XXXX XXXX XXXX XXXX',
|
|
2550
|
-
redaction: Skyflow.RedactionType.MASKED
|
|
2551
|
-
});
|
|
2552
|
-
|
|
2553
|
-
const cvvElement = container.create({
|
|
2554
|
-
token: '89024714-6a26-4256-b9d4-55ad69aa4047',
|
|
2555
|
-
inputStyles: {
|
|
2556
|
-
base: {
|
|
2557
|
-
color: '#1d1d1d',
|
|
2558
|
-
},
|
|
2559
|
-
},
|
|
2560
|
-
label: 'cvv',
|
|
2561
|
-
altText: 'XXX',
|
|
2562
|
-
});
|
|
2563
|
-
|
|
2564
|
-
const expiryDate= container.create({
|
|
2565
|
-
token: 'a4b24714-6a26-4256-b9d4-55ad69aa4047',
|
|
2566
|
-
inputStyles: {
|
|
2567
|
-
base: {
|
|
2568
|
-
color: '#1d1d1d',
|
|
2569
|
-
},
|
|
2570
|
-
},
|
|
2571
|
-
label: 'expiryDate',
|
|
2572
|
-
altText: 'MM/YYYY',
|
|
2573
|
-
});
|
|
2574
|
-
// Step 3.
|
|
2575
|
-
cardNumberElement.mount('#cardNumber'); // Assumes there is a placeholder div with id='cardNumber' on the page
|
|
2576
|
-
cvvElement.mount('#cvv'); // Assumes there is a placeholder div with id='cvv' on the page
|
|
2577
|
-
expiryDate.mount('#expiryDate'); // Assumes there is a placeholder div with id='expiryDate' on the page
|
|
2578
|
-
|
|
2579
|
-
// Step 4.
|
|
2580
|
-
container
|
|
2581
|
-
.reveal()
|
|
2582
|
-
.then(data => {
|
|
2583
|
-
// Handle success.
|
|
2584
|
-
})
|
|
2585
|
-
.catch(err => {
|
|
2586
|
-
// Handle error.
|
|
2587
|
-
});
|
|
2588
|
-
```
|
|
2589
|
-
|
|
2590
|
-
The response below shows that some tokens assigned to the reveal elements get revealed successfully, while others fail and remain unrevealed.
|
|
2591
|
-
|
|
2592
|
-
### Sample Response
|
|
2593
|
-
|
|
2594
|
-
```
|
|
2595
|
-
{
|
|
2596
|
-
"success": [
|
|
2597
|
-
{
|
|
2598
|
-
"token": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
|
|
2599
|
-
"value": "xxxxxxxxx4163"
|
|
2600
|
-
"valueType": "STRING"
|
|
2601
|
-
},
|
|
2602
|
-
{
|
|
2603
|
-
"token": "a4b24714-6a26-4256-b9d4-55ad69aa4047",
|
|
2604
|
-
"value": "12/2098"
|
|
2605
|
-
"valueType": "STRING"
|
|
2606
|
-
}
|
|
2607
|
-
],
|
|
2608
|
-
"errors": [
|
|
2609
|
-
{
|
|
2610
|
-
"token": "89024714-6a26-4256-b9d4-55ad69aa4047",
|
|
2611
|
-
"error": {
|
|
2612
|
-
"code": 404,
|
|
2613
|
-
"description": "Tokens not found for 89024714-6a26-4256-b9d4-55ad69aa4047"
|
|
2614
|
-
}
|
|
2615
|
-
}
|
|
2616
|
-
]
|
|
2617
|
-
}
|
|
2618
|
-
```
|
|
2619
|
-
|
|
2620
|
-
### UI Error for Reveal Elements
|
|
2621
|
-
Helps to display custom error messages on the Skyflow Elements through the methods `setError` and `resetError` on the elements.
|
|
2622
|
-
|
|
2623
|
-
`setError(error: string)` method is used to set the error text for the element, when this method is triggered, all the current errors present on the element will be overridden with the custom error message passed. This error will be displayed on the element until `resetError()` is triggered on the same element.
|
|
2624
|
-
|
|
2625
|
-
`resetError()` method is used to clear the custom error message that is set using `setError`.
|
|
2626
|
-
|
|
2627
|
-
##### Sample code snippet for setError and resetError
|
|
2628
|
-
|
|
2629
|
-
```javascript
|
|
2630
|
-
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
|
|
2631
|
-
|
|
2632
|
-
const cardNumber = container.create({
|
|
2633
|
-
token: '89024714-6a26-4256-b9d4-55ad69aa4047',
|
|
2634
|
-
});
|
|
2635
|
-
|
|
2636
|
-
// Set custom error.
|
|
2637
|
-
cardNumber.setError('custom error');
|
|
2638
|
-
|
|
2639
|
-
// Reset custom error.
|
|
2640
|
-
cardNumber.resetError();
|
|
2641
|
-
```
|
|
2642
|
-
|
|
2643
|
-
### Override default error messages
|
|
2644
|
-
|
|
2645
|
-
You can override the default error messages with custom ones by using `setErrorOverride`. This is especially useful to override default error messages in non-English languages.
|
|
2646
|
-
|
|
2647
|
-
```javascript
|
|
2648
|
-
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
|
|
2649
|
-
|
|
2650
|
-
const cardNumber = container.create({
|
|
2651
|
-
token: '89024714-6a26-4256-b9d4-55ad69aa4047',
|
|
2652
|
-
});
|
|
2653
|
-
|
|
2654
|
-
const revealButton = document.getElementById('revealPCIData');
|
|
2655
|
-
|
|
2656
|
-
if (revealButton) {
|
|
2657
|
-
revealButton.addEventListener('click', () => {
|
|
2658
|
-
revealContainer.reveal().then((res) => {
|
|
2659
|
-
//handle reveal response
|
|
2660
|
-
}).catch((err) => {
|
|
2661
|
-
cardNumber.setErrorOverride("custom error")
|
|
2662
|
-
});
|
|
2663
|
-
});
|
|
2664
|
-
}
|
|
2665
|
-
```
|
|
2666
|
-
|
|
2667
|
-
### Set token for Reveal Elements
|
|
2668
|
-
|
|
2669
|
-
The `setToken(value: string)` method can be used to set the token of the Reveal Element. If no altText is set, the set token will be displayed on the UI as well. If altText is set, then there will be no change in the UI but the token of the element will be internally updated.
|
|
2670
|
-
|
|
2671
|
-
##### Sample code snippet for setToken
|
|
2672
|
-
```javascript
|
|
2673
|
-
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
|
|
2674
|
-
|
|
2675
|
-
const cardNumber = container.create({
|
|
2676
|
-
altText: 'Card Number',
|
|
2677
|
-
});
|
|
2678
|
-
|
|
2679
|
-
// Set token.
|
|
2680
|
-
cardNumber.setToken('89024714-6a26-4256-b9d4-55ad69aa4047');
|
|
2681
|
-
```
|
|
2682
|
-
### Set and Clear altText for Reveal Elements
|
|
2683
|
-
The `setAltText(value: string)` method can be used to set the altText of the Reveal Element. This will cause the altText to be displayed in the UI regardless of whether the token or value is currently being displayed.
|
|
2684
|
-
|
|
2685
|
-
`clearAltText()` method can be used to clear the altText, this will cause the element to display the token or actual value of the element. If the element has no token, the element will be empty.
|
|
2686
|
-
##### Sample code snippet for setAltText and clearAltText
|
|
2687
|
-
|
|
2688
|
-
```javascript
|
|
2689
|
-
const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
|
|
2690
|
-
|
|
2691
|
-
const cardNumber = container.create({
|
|
2692
|
-
token: '89024714-6a26-4256-b9d4-55ad69aa4047',
|
|
2693
|
-
});
|
|
2694
|
-
|
|
2695
|
-
// Set altText.
|
|
2696
|
-
cardNumber.setAltText('Card Number');
|
|
2697
|
-
|
|
2698
|
-
// Clear altText.
|
|
2699
|
-
cardNumber.clearAltText();
|
|
2700
|
-
|
|
2701
|
-
```
|
|
2702
|
-
|
|
2703
|
-
## Using Skyflow File Element to upload a file
|
|
2704
|
-
|
|
2705
|
-
You can upload binary files to a vault using the Skyflow File Element. Use the following steps to securely upload a file.
|
|
2706
|
-
### Step 1: Create a container
|
|
2707
|
-
|
|
2708
|
-
Create a container for the form elements using the container(Skyflow.ContainerType) method of the Skyflow client:
|
|
2709
|
-
|
|
2710
|
-
```javascript
|
|
2711
|
-
const container = skyflowClient.container(Skyflow.ContainerType.COLLECT)
|
|
3993
|
+
|
|
3994
|
+
const revealElement = revealComposableContainer.create(revealElementInput,options);
|
|
2712
3995
|
```
|
|
2713
3996
|
|
|
2714
|
-
|
|
3997
|
+
Value from vault: "1234121234"
|
|
3998
|
+
Revealed Value displayed in element: "(123) 412-1234"
|
|
2715
3999
|
|
|
2716
|
-
|
|
4000
|
+
Example 2:
|
|
4001
|
+
```js
|
|
4002
|
+
const revealElementInput = {
|
|
4003
|
+
token: '<token>'
|
|
4004
|
+
};
|
|
2717
4005
|
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
inputStyles: {}, // Optional, styles that should be applied to the form element.
|
|
2725
|
-
labelStyles: {}, // Optional, styles that will be applied to the label of the collect element.
|
|
2726
|
-
errorTextStyles:{}, // Optional, styles that will be applied to the errorText of the collect element.
|
|
2727
|
-
}
|
|
4006
|
+
const options = {
|
|
4007
|
+
format: 'XXXX-XXXXXX-XXXXX',
|
|
4008
|
+
translation: { 'X': '[0-9]' }
|
|
4009
|
+
};
|
|
4010
|
+
|
|
4011
|
+
const revealElement = revealComposableContainer.create(revealElementInput,options);
|
|
2728
4012
|
```
|
|
2729
|
-
The `table` and `column` fields indicate which table and column the Element corresponds to.
|
|
2730
4013
|
|
|
2731
|
-
|
|
4014
|
+
Value from vault: "374200000000004"
|
|
4015
|
+
Revealed Value displayed in element: "3742-000000-00004"
|
|
2732
4016
|
|
|
2733
|
-
|
|
2734
|
-
- `skyflowID` is required while creating File element
|
|
2735
|
-
- Use period-delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`).
|
|
4017
|
+
Once you've defined a Skyflow Element, you can use the `create(element)` method of the container to create the Element as shown below:
|
|
2736
4018
|
|
|
2737
|
-
|
|
4019
|
+
```javascript
|
|
4020
|
+
const element = revealComposableContainer.create(revealElement)
|
|
4021
|
+
```
|
|
2738
4022
|
|
|
2739
|
-
|
|
4023
|
+
### Step 3: Mount Container to the DOM
|
|
4024
|
+
To specify where the Elements are rendered on your page, create a placeholder `<div>` element with unique `id` attribute. Use this empty `<div>` placeholder to mount the composable reveal container.
|
|
2740
4025
|
|
|
2741
|
-
```
|
|
4026
|
+
```javascript
|
|
2742
4027
|
<form>
|
|
2743
|
-
<div id="
|
|
4028
|
+
<div id="composableRevealContainer"/>
|
|
2744
4029
|
<br/>
|
|
4030
|
+
<div id="button-id"/>
|
|
2745
4031
|
<button type="submit">Submit</button>
|
|
2746
4032
|
</form>
|
|
2747
4033
|
```
|
|
4034
|
+
Use the composable container's `mount(domElement)` method to insert the container's Elements into the specified `<div>`. For instance, the following call inserts Elements into the `<div>` with the `id "#composableContainer"`.
|
|
2748
4035
|
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
```javascript
|
|
2752
|
-
element.mount('#file');
|
|
2753
|
-
```
|
|
2754
|
-
Use the `unmount` method to reset a Collect Element to its initial state.
|
|
2755
|
-
|
|
2756
|
-
```javascript
|
|
2757
|
-
element.unmount();
|
|
4036
|
+
```javacript
|
|
4037
|
+
revealComposableContainer.mount('#composableRevealContainer');
|
|
2758
4038
|
```
|
|
2759
|
-
## Step 4: Collect data from elements
|
|
2760
4039
|
|
|
2761
|
-
|
|
4040
|
+
### Step 4: Reveal data
|
|
4041
|
+
When the sensitive data is ready to be retrieved and revealed, call the `reveal()` method on the container as shown below:
|
|
2762
4042
|
|
|
2763
4043
|
```javascript
|
|
2764
|
-
container
|
|
4044
|
+
container
|
|
4045
|
+
.reveal()
|
|
4046
|
+
.then(data => {
|
|
4047
|
+
// Handle success.
|
|
4048
|
+
})
|
|
4049
|
+
.catch(err => {
|
|
4050
|
+
// Handle error.
|
|
4051
|
+
});
|
|
2765
4052
|
```
|
|
2766
|
-
### File upload limitations:
|
|
2767
|
-
|
|
2768
|
-
- Only non-executable file are allowed to be uploaded.
|
|
2769
|
-
- Files must have a maximum size of 32 MB
|
|
2770
|
-
- File columns can't enable tokenization, redaction, or arrays.
|
|
2771
|
-
- Re-uploading a file overwrites previously uploaded data.
|
|
2772
|
-
- Partial uploads or resuming a previous upload isn't supported.
|
|
2773
|
-
|
|
2774
|
-
### End-to-end file upload
|
|
2775
4053
|
|
|
4054
|
+
### End to end example of reveal data with Composable Reveal Elements
|
|
2776
4055
|
```javascript
|
|
2777
4056
|
// Step 1.
|
|
2778
|
-
const container = skyflowClient.container(Skyflow.ContainerType.
|
|
2779
|
-
|
|
4057
|
+
const container = skyflowClient.container(Skyflow.ContainerType.COMPOSE_REVEAL, containerOptions);
|
|
2780
4058
|
// Step 2.
|
|
2781
|
-
const
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
|
|
2785
|
-
inputstyles: {
|
|
4059
|
+
const cardNumberElement = container.create({
|
|
4060
|
+
token: 'b63ec4e0-bbad-4e43-96e6-6bd50f483f75',
|
|
4061
|
+
inputStyles: {
|
|
2786
4062
|
base: {
|
|
2787
4063
|
color: '#1d1d1d',
|
|
2788
4064
|
},
|
|
@@ -2790,7 +4066,6 @@ const element = container.create({
|
|
|
2790
4066
|
labelStyles: {
|
|
2791
4067
|
base: {
|
|
2792
4068
|
fontSize: '12px',
|
|
2793
|
-
fontWeight: 'bold',
|
|
2794
4069
|
},
|
|
2795
4070
|
},
|
|
2796
4071
|
errorTextStyles: {
|
|
@@ -2798,227 +4073,186 @@ const element = container.create({
|
|
|
2798
4073
|
color: '#f44336',
|
|
2799
4074
|
},
|
|
2800
4075
|
},
|
|
2801
|
-
|
|
4076
|
+
label: 'card_number',
|
|
4077
|
+
altText: 'XXXX XXXX XXXX XXXX',
|
|
4078
|
+
redaction: Skyflow.RedactionType.MASKED
|
|
2802
4079
|
});
|
|
2803
4080
|
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
// Step 4.
|
|
2808
|
-
container.uploadFiles();
|
|
2809
|
-
```
|
|
2810
|
-
|
|
2811
|
-
**Sample Response :**
|
|
2812
|
-
```javascript
|
|
2813
|
-
{
|
|
2814
|
-
fileUploadResponse: [
|
|
2815
|
-
{
|
|
2816
|
-
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
|
|
2817
|
-
}
|
|
2818
|
-
]
|
|
2819
|
-
}
|
|
2820
|
-
```
|
|
2821
|
-
### File upload with options:
|
|
2822
|
-
|
|
2823
|
-
Along with fileElementInput, you can define other options in the Options object as described below:
|
|
2824
|
-
```js
|
|
2825
|
-
const options = {
|
|
2826
|
-
allowedFileType: String[], // Optional, indicates the allowed file types for upload
|
|
2827
|
-
}
|
|
2828
|
-
```
|
|
2829
|
-
`allowedFileType`: An array of string value that indicates the allowedFileTypes to be uploaded.
|
|
2830
|
-
|
|
2831
|
-
#### File upload with options example
|
|
2832
|
-
|
|
2833
|
-
```javascript
|
|
2834
|
-
// Create collect Container.
|
|
2835
|
-
const collectContainer = skyflow.container(Skyflow.ContainerType.COLLECT);
|
|
2836
|
-
|
|
2837
|
-
// Create collect elements.
|
|
2838
|
-
const cardNumberElement = collectContainer.create({
|
|
2839
|
-
table: 'newTable',
|
|
2840
|
-
column: 'card_number',
|
|
2841
|
-
inputstyles: {
|
|
4081
|
+
const cvvElement = container.create({
|
|
4082
|
+
token: '89024714-6a26-4256-b9d4-55ad69aa4047',
|
|
4083
|
+
inputStyles: {
|
|
2842
4084
|
base: {
|
|
2843
4085
|
color: '#1d1d1d',
|
|
2844
4086
|
},
|
|
2845
4087
|
},
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
fontSize: '12px',
|
|
2849
|
-
fontWeight: 'bold',
|
|
2850
|
-
},
|
|
2851
|
-
},
|
|
2852
|
-
errorTextStyles: {
|
|
2853
|
-
base: {
|
|
2854
|
-
color: '#f44336',
|
|
2855
|
-
},
|
|
2856
|
-
},
|
|
2857
|
-
placeholder: 'card number',
|
|
2858
|
-
label: 'Card Number',
|
|
2859
|
-
type: Skyflow.ElementType.CARD_NUMBER,
|
|
4088
|
+
label: 'cvv',
|
|
4089
|
+
altText: 'XXX',
|
|
2860
4090
|
});
|
|
2861
|
-
const options = {
|
|
2862
|
-
allowedFileType: [".pdf",".png"];
|
|
2863
|
-
};
|
|
2864
|
-
const fileElement = collectContainer.create({
|
|
2865
|
-
table: 'newTable',
|
|
2866
|
-
column: 'file',
|
|
2867
|
-
skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
|
|
2868
|
-
inputstyles: {
|
|
2869
|
-
base: {
|
|
2870
|
-
color: '#1d1d1d',
|
|
2871
|
-
},
|
|
2872
|
-
},
|
|
2873
|
-
labelStyles: {
|
|
2874
|
-
base: {
|
|
2875
|
-
fontSize: '12px',
|
|
2876
|
-
fontWeight: 'bold',
|
|
2877
|
-
},
|
|
2878
|
-
},
|
|
2879
|
-
errorTextStyles: {
|
|
2880
|
-
base: {
|
|
2881
|
-
color: '#f44336',
|
|
2882
|
-
},
|
|
2883
|
-
},
|
|
2884
|
-
type: Skyflow.ElementType.FILE_INPUT,
|
|
2885
|
-
},
|
|
2886
|
-
options
|
|
2887
|
-
);
|
|
2888
4091
|
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
4092
|
+
const expiryDate= container.create({
|
|
4093
|
+
token: 'a4b24714-6a26-4256-b9d4-55ad69aa4047',
|
|
4094
|
+
inputStyles: {
|
|
4095
|
+
base: {
|
|
4096
|
+
color: '#1d1d1d',
|
|
4097
|
+
},
|
|
4098
|
+
},
|
|
4099
|
+
label: 'expiryDate',
|
|
4100
|
+
altText: 'MM/YYYY',
|
|
4101
|
+
});
|
|
4102
|
+
// Step 3.
|
|
4103
|
+
container.mount('#container')
|
|
4104
|
+
// Step 4.
|
|
4105
|
+
container
|
|
4106
|
+
.reveal()
|
|
4107
|
+
.then(data => {
|
|
4108
|
+
// Handle success.
|
|
4109
|
+
})
|
|
4110
|
+
.catch(err => {
|
|
4111
|
+
// Handle error.
|
|
4112
|
+
});
|
|
4113
|
+
```
|
|
4114
|
+
The response below shows that some tokens assigned to the reveal elements get revealed successfully, while others fail and remain unrevealed.
|
|
2892
4115
|
|
|
2893
|
-
|
|
2894
|
-
collectContainer.collect({});
|
|
2895
|
-
collectContainer.uploadFiles();
|
|
4116
|
+
### Sample Response
|
|
2896
4117
|
|
|
2897
4118
|
```
|
|
2898
|
-
**Sample Response for collect():**
|
|
2899
|
-
```javascript
|
|
2900
4119
|
{
|
|
2901
|
-
"
|
|
4120
|
+
"success": [
|
|
4121
|
+
{
|
|
4122
|
+
"token": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
|
|
4123
|
+
"value": "xxxxxxxxx4163"
|
|
4124
|
+
"valueType": "STRING"
|
|
4125
|
+
},
|
|
4126
|
+
{
|
|
4127
|
+
"token": "a4b24714-6a26-4256-b9d4-55ad69aa4047",
|
|
4128
|
+
"value": "12/2098"
|
|
4129
|
+
"valueType": "STRING"
|
|
4130
|
+
}
|
|
4131
|
+
],
|
|
4132
|
+
"errors": [
|
|
2902
4133
|
{
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
4134
|
+
"token": "89024714-6a26-4256-b9d4-55ad69aa4047",
|
|
4135
|
+
"error": {
|
|
4136
|
+
"code": 404,
|
|
4137
|
+
"description": "Tokens not found for 89024714-6a26-4256-b9d4-55ad69aa4047"
|
|
4138
|
+
}
|
|
4139
|
+
}
|
|
2908
4140
|
]
|
|
2909
4141
|
}
|
|
2910
4142
|
```
|
|
2911
|
-
|
|
4143
|
+
|
|
4144
|
+
## Update Reveal Composable Elements
|
|
4145
|
+
|
|
4146
|
+
You can update reveal composable element properties with the `update` interface.
|
|
4147
|
+
|
|
4148
|
+
The `update` interface takes the below object:
|
|
2912
4149
|
```javascript
|
|
2913
|
-
{
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
4150
|
+
const updateElement = {
|
|
4151
|
+
token: 'string', // Optional, token of the data being revealed.
|
|
4152
|
+
inputStyles: {}, // Optional, styles to be applied to the element.
|
|
4153
|
+
labelStyles: {}, // Optional, styles to be applied to the label of the reveal element.
|
|
4154
|
+
errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the reveal element.
|
|
4155
|
+
label: 'string', // Optional, label for the form element.
|
|
4156
|
+
altText: 'string', // Optional, string that is shown before reveal, will show token if altText is not provided.
|
|
4157
|
+
redaction: RedactionType, // Optional, Redaction Type to be applied to data.
|
|
4158
|
+
skyflowID: 'string', // Optional, Skyflow ID of the file to render.
|
|
4159
|
+
table: 'string', // Optional, table name of the file to render.
|
|
4160
|
+
column: 'string' // Optional, column name of the file to render.
|
|
4161
|
+
};
|
|
2920
4162
|
```
|
|
2921
|
-
#### File upload with additional elements
|
|
2922
4163
|
|
|
4164
|
+
Only include the properties that you want to update for the specified reveal element.
|
|
4165
|
+
|
|
4166
|
+
Properties your provided when you created the element remain the same until you explicitly update them.
|
|
4167
|
+
|
|
4168
|
+
|
|
4169
|
+
### End to end example
|
|
2923
4170
|
```javascript
|
|
2924
|
-
// Create
|
|
2925
|
-
const
|
|
4171
|
+
// Create a reveal composable container.
|
|
4172
|
+
const revealComposableContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSE_REVEAL, containerOptions);
|
|
2926
4173
|
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
table: 'newTable',
|
|
2930
|
-
column: 'card_number',
|
|
2931
|
-
inputstyles: {
|
|
2932
|
-
base: {
|
|
2933
|
-
color: '#1d1d1d',
|
|
2934
|
-
},
|
|
2935
|
-
},
|
|
2936
|
-
labelStyles: {
|
|
4174
|
+
const stylesOptions = {
|
|
4175
|
+
inputStyles: {
|
|
2937
4176
|
base: {
|
|
2938
|
-
|
|
2939
|
-
|
|
4177
|
+
fontFamily: 'Inter',
|
|
4178
|
+
fontStyle: 'normal',
|
|
4179
|
+
fontWeight: 400,
|
|
4180
|
+
fontSize: '14px',
|
|
4181
|
+
lineHeight: '21px',
|
|
4182
|
+
width: '294px',
|
|
2940
4183
|
},
|
|
2941
4184
|
},
|
|
4185
|
+
labelStyles: {},
|
|
2942
4186
|
errorTextStyles: {
|
|
2943
4187
|
base: {
|
|
2944
|
-
color: '#f44336'
|
|
4188
|
+
color: '#f44336'
|
|
2945
4189
|
},
|
|
2946
4190
|
},
|
|
2947
|
-
|
|
4191
|
+
};
|
|
4192
|
+
|
|
4193
|
+
// Create reveal elements
|
|
4194
|
+
const cardHolderNameRevealElement = revealComposableContainer.create({
|
|
4195
|
+
token: 'ed5fdd1f-5009-435c-a06b-3417ce76d2c8',
|
|
4196
|
+
altText: 'first name',
|
|
4197
|
+
...stylesOptions,
|
|
4198
|
+
label: 'Card Holder Name',
|
|
4199
|
+
});
|
|
4200
|
+
|
|
4201
|
+
const cardNumberRevealElement = revealComposableContainer.create({
|
|
4202
|
+
token: '8ee84061-7107-4faf-bb25-e044f3d191fe',
|
|
4203
|
+
altText: 'xxxx',
|
|
4204
|
+
...stylesOptions,
|
|
2948
4205
|
label: 'Card Number',
|
|
2949
|
-
|
|
4206
|
+
redaction: 'RedactionType.CARD_NUMBER'
|
|
2950
4207
|
});
|
|
2951
4208
|
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
},
|
|
2960
|
-
},
|
|
4209
|
+
// Mount the reveal elements.
|
|
4210
|
+
revealContainer.mount('#container'); // Assumes there is a div with container
|
|
4211
|
+
// ...
|
|
4212
|
+
|
|
4213
|
+
// Update label, labelStyles properties on cardHolderNameRevealElement.
|
|
4214
|
+
cardHolderNameRevealElement.update({
|
|
4215
|
+
label: 'CARDHOLDER NAME',
|
|
2961
4216
|
labelStyles: {
|
|
2962
4217
|
base: {
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
4218
|
+
color: '#aa11aa'
|
|
4219
|
+
}
|
|
4220
|
+
}
|
|
4221
|
+
});
|
|
4222
|
+
|
|
4223
|
+
// Update inputStyles, errorTextStyles properties on cardNumberRevealElement.
|
|
4224
|
+
cardNumberRevealElement.update({
|
|
4225
|
+
inputStyles: {
|
|
4226
|
+
base: {
|
|
4227
|
+
color: '#fff',
|
|
4228
|
+
backgroundColor: '#000',
|
|
4229
|
+
borderColor: '#f00',
|
|
4230
|
+
borderWidth: '5px'
|
|
4231
|
+
}
|
|
2966
4232
|
},
|
|
2967
4233
|
errorTextStyles: {
|
|
2968
4234
|
base: {
|
|
2969
|
-
|
|
2970
|
-
},
|
|
2971
|
-
},
|
|
2972
|
-
type: Skyflow.ElementType.FILE_INPUT,
|
|
2973
|
-
});
|
|
2974
|
-
|
|
2975
|
-
// Mount the elements.
|
|
2976
|
-
cardNumberElement.mount('#collectCardNumber');
|
|
2977
|
-
fileElement.mount('#collectFile');
|
|
2978
|
-
|
|
2979
|
-
// Collect and upload methods.
|
|
2980
|
-
collectContainer.collect({});
|
|
2981
|
-
collectContainer.uploadFiles();
|
|
2982
|
-
|
|
2983
|
-
```
|
|
2984
|
-
**Sample Response for collect():**
|
|
2985
|
-
```javascript
|
|
2986
|
-
{
|
|
2987
|
-
"records": [
|
|
2988
|
-
{
|
|
2989
|
-
"table": "newTable",
|
|
2990
|
-
"fields": {
|
|
2991
|
-
"card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
|
|
2992
|
-
}
|
|
4235
|
+
backgroundColor: '#000',
|
|
2993
4236
|
}
|
|
2994
|
-
|
|
2995
|
-
}
|
|
2996
|
-
```
|
|
2997
|
-
**Sample Response for file uploadFiles() :**
|
|
2998
|
-
```javascript
|
|
2999
|
-
{
|
|
3000
|
-
"fileUploadResponse": [
|
|
3001
|
-
{
|
|
3002
|
-
"skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
|
|
3003
|
-
}
|
|
3004
|
-
]
|
|
3005
|
-
}
|
|
4237
|
+
}
|
|
4238
|
+
});
|
|
3006
4239
|
```
|
|
3007
4240
|
|
|
3008
|
-
|
|
4241
|
+
---
|
|
3009
4242
|
|
|
3010
|
-
|
|
4243
|
+
|
|
4244
|
+
## Render a file with a Composable File Element
|
|
3011
4245
|
|
|
3012
4246
|
You can render files using the Skyflow File Element. Use the following steps to securely render a file.
|
|
3013
4247
|
|
|
3014
|
-
|
|
4248
|
+
### Step 1: Create a container
|
|
3015
4249
|
Create a container for the form elements using the container(Skyflow.ContainerType) method of the Skyflow client:
|
|
3016
4250
|
|
|
3017
4251
|
```javascript
|
|
3018
|
-
const container = skyflowClient.container(Skyflow.ContainerType.
|
|
4252
|
+
const container = skyflowClient.container(Skyflow.ContainerType.COMPOSE_REVEAL, containerOptions)
|
|
3019
4253
|
```
|
|
3020
4254
|
|
|
3021
|
-
|
|
4255
|
+
### Step 2: Create a File Element
|
|
3022
4256
|
Define a Skyflow Element to render the file as shown below.
|
|
3023
4257
|
|
|
3024
4258
|
```javascript
|
|
@@ -3057,11 +4291,11 @@ errorTextStyles: {
|
|
|
3057
4291
|
}
|
|
3058
4292
|
}
|
|
3059
4293
|
```
|
|
3060
|
-
|
|
3061
|
-
Elements
|
|
4294
|
+
### Step 3: Mount Container to the DOM
|
|
4295
|
+
Mount Elements for file rendering to the DOM the same way as Elements used for revealing data. Refer to Step 3 of the [section above](#step-3-mount-container-to-the-dom).
|
|
3062
4296
|
|
|
3063
|
-
|
|
3064
|
-
|
|
4297
|
+
### Step 4: Render File
|
|
4298
|
+
After you create and mount the element, call the renderFile() method on the element as shown below:
|
|
3065
4299
|
```javascript
|
|
3066
4300
|
fileElement
|
|
3067
4301
|
.renderFile()
|
|
@@ -3073,10 +4307,10 @@ fileElement
|
|
|
3073
4307
|
});
|
|
3074
4308
|
```
|
|
3075
4309
|
|
|
3076
|
-
|
|
4310
|
+
### End to end example of file render
|
|
3077
4311
|
```javascript
|
|
3078
4312
|
// Step 1.
|
|
3079
|
-
const container = skyflowClient.container(Skyflow.ContainerType.
|
|
4313
|
+
const container = skyflowClient.container(Skyflow.ContainerType.COMPOSE_REVEAL, containerOptions);
|
|
3080
4314
|
|
|
3081
4315
|
// REPLACE with your custom implementation to fetch skyflow_id from backend service.
|
|
3082
4316
|
// Sample implementation
|
|
@@ -3131,117 +4365,6 @@ fetch("<BACKEND_URL>")
|
|
|
3131
4365
|
|
|
3132
4366
|
```
|
|
3133
4367
|
|
|
3134
|
-
## Sample Success Response
|
|
3135
|
-
```json
|
|
3136
|
-
{
|
|
3137
|
-
"success": [
|
|
3138
|
-
{
|
|
3139
|
-
"skyflow_id": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
|
|
3140
|
-
"column": "file"
|
|
3141
|
-
},
|
|
3142
|
-
]
|
|
3143
|
-
}
|
|
3144
|
-
```
|
|
3145
|
-
|
|
3146
|
-
### Update Reveal Elements
|
|
3147
|
-
|
|
3148
|
-
You can update reveal element properties with the `update` interface.
|
|
3149
|
-
|
|
3150
|
-
The `update` interface takes the below object:
|
|
3151
|
-
```javascript
|
|
3152
|
-
const updateElement = {
|
|
3153
|
-
token: 'string', // Optional, token of the data being revealed.
|
|
3154
|
-
inputStyles: {}, // Optional, styles to be applied to the element.
|
|
3155
|
-
labelStyles: {}, // Optional, styles to be applied to the label of the reveal element.
|
|
3156
|
-
errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the reveal element.
|
|
3157
|
-
label: 'string', // Optional, label for the form element.
|
|
3158
|
-
altText: 'string', // Optional, string that is shown before reveal, will show token if altText is not provided.
|
|
3159
|
-
redaction: RedactionType, // Optional, Redaction Type to be applied to data.
|
|
3160
|
-
skyflowID: 'string', // Optional, Skyflow ID of the file to render.
|
|
3161
|
-
table: 'string', // Optional, table name of the file to render.
|
|
3162
|
-
column: 'string' // Optional, column name of the file to render.
|
|
3163
|
-
};
|
|
3164
|
-
```
|
|
3165
|
-
|
|
3166
|
-
Only include the properties that you want to update for the specified reveal element.
|
|
3167
|
-
|
|
3168
|
-
Properties your provided when you created the element remain the same until you explicitly update them.
|
|
3169
|
-
|
|
3170
|
-
### End to end example
|
|
3171
|
-
```javascript
|
|
3172
|
-
// Create a reveal container.
|
|
3173
|
-
const revealContainer = skyflow.container(Skyflow.ContainerType.REVEAL);
|
|
3174
|
-
|
|
3175
|
-
const stylesOptions = {
|
|
3176
|
-
inputStyles: {
|
|
3177
|
-
base: {
|
|
3178
|
-
fontFamily: 'Inter',
|
|
3179
|
-
fontStyle: 'normal',
|
|
3180
|
-
fontWeight: 400,
|
|
3181
|
-
fontSize: '14px',
|
|
3182
|
-
lineHeight: '21px',
|
|
3183
|
-
width: '294px',
|
|
3184
|
-
},
|
|
3185
|
-
},
|
|
3186
|
-
labelStyles: {},
|
|
3187
|
-
errorTextStyles: {
|
|
3188
|
-
base: {
|
|
3189
|
-
color: '#f44336'
|
|
3190
|
-
},
|
|
3191
|
-
},
|
|
3192
|
-
};
|
|
3193
|
-
|
|
3194
|
-
// Create reveal elements
|
|
3195
|
-
const cardHolderNameRevealElement = revealContainer.create({
|
|
3196
|
-
token: 'ed5fdd1f-5009-435c-a06b-3417ce76d2c8',
|
|
3197
|
-
altText: 'first name',
|
|
3198
|
-
...stylesOptions,
|
|
3199
|
-
label: 'Card Holder Name',
|
|
3200
|
-
});
|
|
3201
|
-
|
|
3202
|
-
const cardNumberRevealElement = revealContainer.create({
|
|
3203
|
-
token: '8ee84061-7107-4faf-bb25-e044f3d191fe',
|
|
3204
|
-
altText: 'xxxx',
|
|
3205
|
-
...stylesOptions,
|
|
3206
|
-
label: 'Card Number',
|
|
3207
|
-
redaction: 'RedactionType.CARD_NUMBER'
|
|
3208
|
-
});
|
|
3209
|
-
|
|
3210
|
-
// Mount the reveal elements.
|
|
3211
|
-
cardHolderNameRevealElement.mount('#cardHolderNameRevealElement'); // Assumes there is a div with id='#cardHolderNameRevealElement' in the webpage.
|
|
3212
|
-
cardNumberRevealElement.mount('#cardNumberRevealElement'); // Assumes there is a div with id='#cardNumberRevealElement' in the webpage.
|
|
3213
|
-
|
|
3214
|
-
// ...
|
|
3215
|
-
|
|
3216
|
-
// Update label, labelStyles properties on cardHolderNameRevealElement.
|
|
3217
|
-
cardHolderNameRevealElement.update({
|
|
3218
|
-
label: 'CARDHOLDER NAME',
|
|
3219
|
-
labelStyles: {
|
|
3220
|
-
base: {
|
|
3221
|
-
color: '#aa11aa'
|
|
3222
|
-
}
|
|
3223
|
-
}
|
|
3224
|
-
});
|
|
3225
|
-
|
|
3226
|
-
// Update inputStyles, errorTextStyles properties on cardNumberRevealElement.
|
|
3227
|
-
cardNumberRevealElement.update({
|
|
3228
|
-
inputStyles: {
|
|
3229
|
-
base: {
|
|
3230
|
-
color: '#fff',
|
|
3231
|
-
backgroundColor: '#000',
|
|
3232
|
-
borderColor: '#f00',
|
|
3233
|
-
borderWidth: '5px'
|
|
3234
|
-
}
|
|
3235
|
-
},
|
|
3236
|
-
errorTextStyles: {
|
|
3237
|
-
base: {
|
|
3238
|
-
backgroundColor: '#000',
|
|
3239
|
-
}
|
|
3240
|
-
}
|
|
3241
|
-
});
|
|
3242
|
-
```
|
|
3243
|
-
|
|
3244
|
-
---
|
|
3245
4368
|
# Securely deleting data client-side
|
|
3246
4369
|
- [**Deleting data from the vault**](#deleting-data-from-the-vault)
|
|
3247
4370
|
|
|
@@ -3297,7 +4420,75 @@ A sample response:
|
|
|
3297
4420
|
}
|
|
3298
4421
|
```
|
|
3299
4422
|
|
|
4423
|
+
# Set Custom Network messages on container:
|
|
4424
|
+
|
|
4425
|
+
Add custom network error messages to a container with the `setError` method.
|
|
4426
|
+
|
|
4427
|
+
`setError(ErrorMessages: Record<ErrorType, string>)` sets the error text for the different network errors types. When this method is triggered, all the errors present in the error response are overridden with the specified custom error message. This error is sent on the collect or upload file call on the same container.
|
|
4428
|
+
|
|
4429
|
+
### Sample code snippet for setError on collect container
|
|
4430
|
+
```javascript
|
|
4431
|
+
const container = skyflowClient.container(Skyflow.ContainerType.COLLECT);
|
|
4432
|
+
|
|
4433
|
+
const cardNumber = container.create({
|
|
4434
|
+
table: 'pii_fields',
|
|
4435
|
+
column: 'primary_card.card_number',
|
|
4436
|
+
type: Skyflow.ElementType.CARD_NUMBER,
|
|
4437
|
+
});
|
|
4438
|
+
|
|
4439
|
+
// Set custom error.
|
|
4440
|
+
container.setError({
|
|
4441
|
+
[Skyflow.ErrorType.BAD_REQUEST]: "Bad request. Please check the request payload.",
|
|
4442
|
+
[Skyflow.ErrorType.UNAUTHORIZED]: "You are not authorized. Please check your token.",
|
|
4443
|
+
[Skyflow.ErrorType.FORBIDDEN]: "Access denied. You do not have permission to perform this action.",
|
|
4444
|
+
[Skyflow.ErrorType.TOO_MANY_REQUESTS]: "Too many requests. Please try again later.",
|
|
4445
|
+
[Skyflow.ErrorType.INTERNAL_SERVER_ERROR]: "Something went wrong on our end. Please try again later.",
|
|
4446
|
+
[Skyflow.ErrorType.BAD_GATEWAY]: "Received an invalid response from the server. Please try again.",
|
|
4447
|
+
[Skyflow.ErrorType.SERVICE_UNAVAILABLE]: "Service is temporarily unavailable. Please try again later.",
|
|
4448
|
+
[Skyflow.ErrorType.CONNECTION]: "Unable to connect to the server. Please check your network connection.",
|
|
4449
|
+
[Skyflow.ErrorType.NOT_FOUND]: "Table not found with custom message",
|
|
4450
|
+
[Skyflow.ErrorType.OFFLINE]: "You appear to be offline. Please check your internet connection.",
|
|
4451
|
+
[Skyflow.ErrorType.TIMEOUT]: "The request took too long to respond. Please try again.",
|
|
4452
|
+
[Skyflow.ErrorType.ABORT]: "The request was aborted.",
|
|
4453
|
+
[Skyflow.ErrorType.NETWORK_GENERIC]: "A network error occurred. Please try again.",
|
|
4454
|
+
});
|
|
4455
|
+
|
|
4456
|
+
container
|
|
4457
|
+
.collect()
|
|
4458
|
+
.then(res => console.log(res))
|
|
4459
|
+
.catch(err =>{
|
|
4460
|
+
console.log(err);
|
|
4461
|
+
})
|
|
4462
|
+
```
|
|
4463
|
+
#### Sample Error structure:
|
|
4464
|
+
```json
|
|
4465
|
+
{
|
|
4466
|
+
"error":{
|
|
4467
|
+
"code":0,
|
|
4468
|
+
"description":"You appear to be offline. Please check your internet connection.",
|
|
4469
|
+
"type":"OFFLINE"
|
|
4470
|
+
},
|
|
4471
|
+
}
|
|
4472
|
+
```
|
|
4473
|
+
|
|
4474
|
+
`Skyflow.ErrorType` accepts following values:
|
|
4475
|
+
- `BAD_REQUEST`
|
|
4476
|
+
- `UNAUTHORIZED`
|
|
4477
|
+
- `FORBIDDEN`
|
|
4478
|
+
- `TOO_MANY_REQUESTS`
|
|
4479
|
+
- `INTERNAL_SERVER_ERROR`
|
|
4480
|
+
- `BAD_GATEWAY`
|
|
4481
|
+
- `SERVICE_UNAVAILABLE`
|
|
4482
|
+
- `CONNECTION`
|
|
4483
|
+
- `NOT_FOUND`
|
|
4484
|
+
- `OFFLINE`
|
|
4485
|
+
- `TIMEOUT`
|
|
4486
|
+
- `NETWORK_GENERIC`
|
|
4487
|
+
- `ABORT`
|
|
4488
|
+
|
|
3300
4489
|
|
|
3301
4490
|
## Reporting a Vulnerability
|
|
3302
4491
|
|
|
3303
4492
|
If you discover a potential security issue in this project, please reach out to us at security@skyflow.com. Please do not create public GitHub issues or Pull Requests, as malicious actors could potentially view them.
|
|
4493
|
+
|
|
4494
|
+
|