skyflow-js 1.24.0 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # skyflow-js
2
- Skyflow’s Javascript SDK can be used to securely collect, tokenize, and reveal sensitive data in the browser without exposing your front-end infrastructure to sensitive data.
2
+ Skyflow’s JavaScript SDK can be used to securely collect, tokenize, and reveal sensitive data in the browser without exposing your front-end infrastructure to sensitive data.
3
3
 
4
4
  ---
5
5
 
@@ -11,6 +11,7 @@ Skyflow’s Javascript SDK can be used to securely collect, tokenize, and reveal
11
11
  - [**Including Skyflow.js**](#Including-Skyflowjs)
12
12
  - [**Initializing Skyflow.js**](#Initializing-Skyflowjs)
13
13
  - [**Securely collecting data client-side**](#Securely-collecting-data-client-side)
14
+ - [**Securely collecting data client-side using Composable Elements**](#Securely-collecting-data-client-side-using-Composable-Elements)
14
15
  - [**Securely revealing data client-side**](#Securely-revealing-data-client-side)
15
16
 
16
17
  ---
@@ -140,9 +141,9 @@ To insert data into the vault, use the `insert(records, options?)` method of the
140
141
  const records = {
141
142
  records: [
142
143
  {
143
- table: 'string', // Table into which record should be inserted.
144
+ table: 'string', // Table into which record should be inserted.
144
145
  fields: {
145
- column1: 'value', // Column names should match vault column names.
146
+ column1: 'value', // Column names should match vault column names.
146
147
  //...additional fields here
147
148
  },
148
149
  },
@@ -151,11 +152,11 @@ const records = {
151
152
  };
152
153
 
153
154
  const options = {
154
- tokens: true, // Indicates whether or not tokens should be returned for the inserted data. Defaults to 'true'
155
- upsert: [ // Upsert operations support in the vault
155
+ tokens: true, // Indicates whether or not tokens should be returned for the inserted data. Defaults to 'true'
156
+ upsert: [ // Upsert operations support in the vault
156
157
  {
157
- table: 'string', // Table name
158
- column: 'value', // Unique column in the table
158
+ table: 'string', // Table name
159
+ column: 'value', // Unique column in the table
159
160
  }
160
161
  ]
161
162
  }
@@ -229,13 +230,13 @@ The `table` and `column` fields indicate which table and column in the vault the
229
230
  - Use dot delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`)
230
231
 
231
232
  The `inputStyles` field accepts a style object which consists of CSS properties that should be applied to the form element in the following states:
232
- - `base`: all other variants inherit from these styles
233
- - `complete`: applied when the Element has valid input
234
- - `empty`: applied when the Element has no input
235
- - `focus`: applied when the Element has focus
236
- - `invalid`: applied when the Element has invalid input
237
- - `cardIcon`: applied to the card type icon in `CARD_NUMBER` Element
238
- - `copyIcon`: applied to copy icon in Elements when `enableCopy` option is true
233
+ * `base`: all variants inherit from these styles
234
+ * `complete`: applied when the Element has valid input
235
+ * `empty`: applied when the Element has no input
236
+ * `focus`: applied when the Element has focus
237
+ * `invalid`: applied when the Element has invalid input
238
+ * `cardIcon`: applied to the card type icon in CARD_NUMBER Element
239
+ * `copyIcon`: applied to copy icon in Elements when enableCopy option is true
239
240
 
240
241
  Styles are specified with [JSS](https://cssinjs.org/?v=v10.7.1).
241
242
 
@@ -307,7 +308,7 @@ Finally, the `type` field takes a Skyflow ElementType. Each type applies the app
307
308
  - `FILE_INPUT`
308
309
 
309
310
 
310
- The `INPUT_FIELD` type is a custom UI element without any built-in validations. See the section on [validations](#validations) for more information on validations.
311
+ The `INPUT_FIELD` type is a custom UI element without any built-in validations. For information on validations, see [validations](#validations).
311
312
 
312
313
  Along with CollectElement we can define other options which takes a object of optional parameters as described below:
313
314
 
@@ -403,26 +404,25 @@ When the form is ready to be submitted, call the `collect(options?)` method on t
403
404
 
404
405
  ```javascript
405
406
  const options = {
406
- tokens: true, // Optional, indicates whether tokens for the collected data should be returned. Defaults to 'true'.
407
+ tokens: true, // Optional, indicates whether tokens for the collected data should be returned. Defaults to 'true'.
407
408
  additionalFields: {
408
409
  records: [
409
410
  {
410
- table: 'string', // Table into which record should be inserted.
411
+ table: 'string', // Table into which record should be inserted.
411
412
  fields: {
412
- column1: 'value', // Column names should match vault column names.
413
+ column1: 'value', // Column names should match vault column names.
413
414
  // ...additional fields here.
414
415
  },
415
416
  },
416
417
  // ...additional records here.
417
418
  ],
418
- }, // Optional
419
- upsert: [
420
- // Upsert operations support in the vault
419
+ }, // Optional
420
+ upsert: [ // Upsert operations support in the vault
421
421
  {
422
- table: 'string', // Table name
423
- column: 'value', // Unique column in the table
422
+ table: 'string', // Table name
423
+ column: 'value', // Unique column in the table
424
424
  },
425
- ], // Optional
425
+ ], // Optional
426
426
  };
427
427
 
428
428
  container.collect(options);
@@ -512,78 +512,78 @@ const container = skyflowClient.container(Skyflow.ContainerType.COLLECT)
512
512
 
513
513
  //Step 2
514
514
  const cardNumberElement = container.create({
515
- table: "cards",
516
- column: "card_number",
515
+ table: 'cards',
516
+ column: 'card_number',
517
517
  inputStyles: {
518
518
  base: {
519
- color: "#1d1d1d",
519
+ color: '#1d1d1d',
520
520
  },
521
521
  cardIcon:{
522
- position: "absolute",
523
- left:"8px",
524
- bottom:"calc(50% - 12px)"
522
+ position: 'absolute',
523
+ left:'8px',
524
+ bottom:'calc(50% - 12px)'
525
525
  },
526
526
  },
527
527
  labelStyles: {
528
528
  base: {
529
- fontSize: "12px",
530
- fontWeight: "bold"
529
+ fontSize: '12px',
530
+ fontWeight: 'bold'
531
531
  }
532
532
  },
533
533
  errorTextStyles: {
534
534
  base: {
535
- color: "#f44336"
535
+ color: '#f44336'
536
536
  }
537
537
  },
538
- placeholder: "Card Number",
539
- label: "card_number",
538
+ placeholder: 'Card Number',
539
+ label: 'card_number',
540
540
  type: Skyflow.ElementType.CARD_NUMBER
541
541
  })
542
-
542
+
543
+
543
544
  const cvvElement = container.create({
544
- table: "cards",
545
- column: "cvv",
545
+ table: 'cards',
546
+ column: 'cvv',
546
547
  inputStyles: {
547
548
  base: {
548
- color: "#1d1d1d",
549
+ color: '#1d1d1d',
549
550
  },
550
551
  cardIcon:{
551
- position: "absolute",
552
- left:"8px",
553
- bottom:"calc(50% - 12px)"
552
+ position: 'absolute',
553
+ left:'8px',
554
+ bottom:'calc(50% - 12px)'
554
555
  },
555
556
  },
556
557
  labelStyles: {
557
558
  base: {
558
- fontSize: "12px",
559
- fontWeight: "bold"
559
+ fontSize: '12px',
560
+ fontWeight: 'bold'
560
561
  }
561
562
  },
562
563
  errorTextStyles: {
563
564
  base: {
564
- color: "#f44336"
565
+ color: '#f44336'
565
566
  }
566
567
  },
567
- placeholder: "CVV",
568
- label: "cvv",
568
+ placeholder: 'CVV',
569
+ label: 'cvv',
569
570
  type: Skyflow.ElementType.CVV
570
571
  })
571
572
 
572
573
  // Step 3
573
- cardNumberElement.mount("#cardNumber") //Assumes there is a div with id="#cardNumber" in the webpage.
574
- cvvElement.mount("#cvv"); //Assumes there is a div with id="#cvv" in the webpage.
574
+ cardNumberElement.mount('#cardNumber') //Assumes there is a div with id='#cardNumber' in the webpage.
575
+ cvvElement.mount('#cvv'); //Assumes there is a div with id='#cvv' in the webpage.
575
576
 
576
577
  // Step 4
577
578
  container.collect({
578
579
  tokens: true,
579
580
  upsert: [
580
581
  {
581
- table: "cards",
582
- column: "card_number",
582
+ table: 'cards',
583
+ column: 'card_number',
583
584
  }
584
585
  ]
585
586
  })
586
-
587
587
  ```
588
588
  **Skyflow returns tokens for the record you just inserted.**
589
589
  ```javascript
@@ -707,7 +707,7 @@ const elementMatchRule = {
707
707
  type: Skyflow.ValidationRuleType.ELEMENT_VALUE_MATCH_RULE,
708
708
  params: {
709
709
  element: pinElement,
710
- error: "PIN doesn't match",
710
+ error: 'PIN does not match',
711
711
  },
712
712
  };
713
713
 
@@ -758,9 +758,9 @@ state : {
758
758
  ```
759
759
 
760
760
  `Note:`
761
- values of SkyflowElements will be returned in elementstate object only when `env` is `DEV`, else it is empty string i.e, ''
761
+ values of SkyflowElements will be returned in element state object only when `env` is `DEV`, else it is empty string i.e, '', but in case of CARD_NUMBER type element when the `env` is `PROD` for all the card types except AMEX, it will return first eight digits, for AMEX it will return first six digits and rest all digits in masked format.
762
762
 
763
- ##### Sample [code snippet](https://github.com/skyflowapi/skyflow-js/blob/master/samples/using-script-tag/collect-element-listeners.html) for using listeners
763
+ ##### Sample [code snippet](https://github.com/skyflowapi/skyflow-js/blob/master/samples/using-script-tag/collect-element-listeners.html) for using listeners
764
764
  ```javascript
765
765
  // Create Skyflow client.
766
766
  const skyflowClient = Skyflow.init({
@@ -774,6 +774,11 @@ const skyflowClient = Skyflow.init({
774
774
 
775
775
  const container = skyflowClient.container(Skyflow.ContainerType.COLLECT);
776
776
 
777
+ const cardHolderName = container.create({
778
+ table: 'pii_fields',
779
+ column: 'first_name',
780
+ type: Skyflow.ElementType.CARDHOLDER_NAME,
781
+ });
777
782
  const cardNumber = container.create({
778
783
  table: 'pii_fields',
779
784
  column: 'primary_card.card_number',
@@ -781,6 +786,13 @@ const cardNumber = container.create({
781
786
  });
782
787
 
783
788
  cardNumber.mount('#cardNumberContainer');
789
+ cardHolderName.mount('#cardHolderNameContainer');
790
+
791
+ // Subscribing to CHANGE event, which gets triggered when element changes.
792
+ cardHolderName.on(Skyflow.EventName.CHANGE, state => {
793
+ // Your implementation when Change event occurs.
794
+ console.log(state);
795
+ });
784
796
 
785
797
  // Subscribing to CHANGE event, which gets triggered when element changes.
786
798
  cardNumber.on(Skyflow.EventName.CHANGE, state => {
@@ -792,24 +804,39 @@ cardNumber.on(Skyflow.EventName.CHANGE, state => {
792
804
  ##### Sample Element state object when `env` is `DEV`
793
805
 
794
806
  ```javascript
807
+ {
808
+ elementType: 'CARDHOLDER_NAME',
809
+ isEmpty: false,
810
+ isFocused: true,
811
+ isValid: false,
812
+ value: 'John',
813
+ };
795
814
  {
796
815
  elementType: 'CARD_NUMBER',
797
816
  isEmpty: false,
798
817
  isFocused: true,
799
818
  isValid: false,
800
- value: '411',
819
+ value: '4111-1111-1111-1111',
801
820
  };
802
821
  ```
803
822
  ##### Sample Element state object when `env` is `PROD`
804
823
 
805
824
  ```javascript
806
825
  {
807
- elementType: 'CARD_NUMBER',
826
+ elementType: 'CARDHOLDER_NAME',
808
827
  isEmpty: false,
809
828
  isFocused: true,
810
829
  isValid: false,
811
830
  value: '',
812
831
  };
832
+ {
833
+ elementType: 'CARD_NUMBER',
834
+ isEmpty: false,
835
+ isFocused: true,
836
+ isValid: false,
837
+ value: '4111-1111-XXXX-XXXX',
838
+ };
839
+
813
840
  ```
814
841
 
815
842
  ### UI Error for Collect Elements
@@ -867,7 +894,446 @@ cardNumber.clearValue();
867
894
 
868
895
  ---
869
896
 
897
+ # Securely collecting data client-side using Composable Elements
898
+
899
+ 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.
900
+
901
+ ### Step 1: Create a composable container
902
+
903
+ Create a container for the composable element using the `container(Skyflow.ContainerType)` method of the Skyflow client:
904
+
905
+ ``` javascript
906
+ const collectContainer = skyflow.container(Skyflow.ContainerType.COMPOSABLE,containerOptions);
907
+ ```
908
+ The container requires an options object that contains the following keys:
909
+
910
+ 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.
911
+
912
+ For example: `[2,1]` means the container has two rows, with two elements in the first row and one element in the second row.
913
+
914
+ `Note`: The sum of values in the layout array should be equal to the number of elements created
915
+
916
+ 2. `styles`: CSS styles to apply to the composable container.
917
+ 3. `errorTextStyles`: CSS styles to apply if an error is encountered.
918
+
919
+ ```javascript
920
+ const options = {
921
+ layout: [2, 1], // Required
922
+ styles: { // Optional
923
+ base: {
924
+ border: '1px solid #DFE3EB',
925
+ padding: '8px',
926
+ borderRadius: '4px',
927
+ margin: '12px 2px',
928
+ },
929
+ },
930
+ errorTextStyles: { // Optional
931
+ base: {
932
+ color: 'red',
933
+ },
934
+ },
935
+ };
936
+ ```
937
+
938
+ ### Step 2: Create Composable Elements
939
+ Composable Elements use the following schema:
940
+
941
+ ```javascript
942
+ const composableElement = {
943
+ table: 'string', // Required. The table this data belongs to.
944
+ column: 'string', // Required. The column this data belongs to.
945
+ type: Skyflow.ElementType, // Skyflow.ElementType enum.
946
+ inputStyles: {}, // Optional. Styles applied to the form element.
947
+ labelStyles: {}, // Optional. Styles for the label of the collect element.
948
+ errorTextStyles: {}, // Optional. Styles for the errorText of the collect element.
949
+ label: 'string', // Optional. Label for the form element.
950
+ placeholder: 'string', // Optional. Placeholder for the form element.
951
+ altText: 'string', // (DEPRECATED) Initial value for the collect element.
952
+ validations: [], // Optional. Array of validation rules.
953
+ }
954
+ ```
955
+ The `table` and `column` fields indicate which table and column in the vault the Element correspond to.
956
+
957
+ Note: Use dot-delimited strings to specify columns nested inside JSON fields (for example, `address.street.line1`).
958
+
959
+ All elements can be styled with [JSS](https://cssinjs.org/?v=v10.7.1) syntax.
960
+
961
+ The `inputStyles` field accepts an object of CSS properties to apply to the form element in the following states:
962
+
963
+ * `base`: all variants inherit from these styles
964
+ * `complete`: applied when the Element has valid input
965
+ * `empty`: applied when the Element has no input
966
+ * `focus`: applied when the Element has focus
967
+ * `invalid`: applied when the Element has invalid input
968
+ * `cardIcon`: applied to the card type icon in CARD_NUMBER Element
969
+ * `copyIcon`: applied to copy icon in Elements when enableCopy option is true
970
+
971
+ An example of an `inputStyles` object:
972
+
973
+ ```javascript
974
+ inputStyles: {
975
+ base: {
976
+ border: '1px solid #eae8ee',
977
+ padding: '10px 16px',
978
+ borderRadius: '4px',
979
+ color: '#1d1d1d',
980
+ },
981
+ complete: {
982
+ color: '#4caf50',
983
+ },
984
+ empty: {},
985
+ focus: {},
986
+ invalid: {
987
+ color: '#f44336',
988
+ },
989
+ cardIcon: {
990
+ position: 'absolute',
991
+ left: '8px',
992
+ bottom: 'calc(50% - 12px)',
993
+ },
994
+ copyIcon: {
995
+ position: 'absolute',
996
+ right: '8px',
997
+ },
998
+ }
999
+ ```
1000
+ The `labelStyles` field supports the `base` and `focus` states.
1001
+
1002
+ An example `labelStyles` object:
1003
+
1004
+ ```javascript
1005
+ labelStyles: {
1006
+ base: {
1007
+ fontSize: '12px',
1008
+ fontWeight: 'bold'
1009
+ },
1010
+ focus: {
1011
+ color: '#1d1d1d'
1012
+ }
1013
+ }
1014
+ ```
1015
+ The `errorTextStyles` field only supports the `base` state, which appears when there is an error in the composable element.
1016
+
1017
+ An example `errorTextStyles` object:
1018
+
1019
+ ```javascript
1020
+ errorTextStyles: {
1021
+ base: {
1022
+ color: '#f44336'
1023
+ }
1024
+ }
1025
+ ```
1026
+ The JS SDK supports the following composable elements:
1027
+
1028
+ - `CARDHOLDER_NAME`
1029
+ - `CARD_NUMBER`
1030
+ - `EXPIRATION_DATE`
1031
+ - `EXPIRATION_MONTH`
1032
+ - `EXPIRATION_YEAR`
1033
+ - `CVV`
1034
+ - `INPUT_FIELD`
1035
+ - `PIN`
1036
+
1037
+ `Note`: Only when the entered value in the below composable elements is valid, the focus shifts automatically. The element types are:
1038
+ - `CARD_NUMBER`
1039
+ - `EXPIRATION_DATE`
1040
+ - `EXPIRATION_MONTH`
1041
+ - `EXPIRATION_YEAR`
1042
+
1043
+ The `INPUT_FIELD` type is a custom UI element without any built-in validations. For information on validations, see [validations](#validations).
1044
+
1045
+ Along with the Composable Element definition, you can define additional options for the element:
1046
+
1047
+ ```javascript
1048
+ const options = {
1049
+ required: false, // Optional, indicates whether the field is marked as required. Defaults to 'false'
1050
+ enableCardIcon: true, // Optional, indicates whether card icon should be enabled (only applicable for CARD_NUMBER ElementType)
1051
+ format: String, // Optional, format for the element (only applicable currently for EXPIRATION_DATE ElementType),
1052
+ enableCopy: false // Optional, enables the copy icon in collect and reveal elements to copy text to clipboard. Defaults to 'false')
1053
+ }
1054
+ ```
1055
+
1056
+ - `required`: Whether or not the field is marked as required. Defaults to `false`.
1057
+ - `enableCardIcon`: Whether or not the icon is visible for the CARD_NUMBER element. Defaults to `true`.
1058
+ - `format`: Format pattern for the element. Only applicable to EXPIRATION_DATE and EXPIRATION_YEAR element types.
1059
+ - `enableCopy`: Whether or not the copy icon is visible in collect and reveal elements. Defaults to `false`.
1060
+
1061
+ The accepted `EXPIRATION_DATE` values are
1062
+
1063
+ - `MM/YY` (default)
1064
+ - `MM/YYYY`
1065
+ - `YY/MM`
1066
+ - `YYYY/MM`
1067
+
1068
+
1069
+ The accepted `EXPIRATION_YEAR` values are
1070
+
1071
+ - `YY` (default)
1072
+ - `YYYY`
1073
+
1074
+
1075
+ Once you define the Element object and options, add it to the container using the `create(element, options)` method:
1076
+
1077
+ ```javascript
1078
+ const composableElement = {
1079
+ table: 'string', // Required, the table this data belongs to.
1080
+ column: 'string', // Required, the column into which this data should be inserted.
1081
+ type: Skyflow.ElementType, // Skyflow.ElementType enum.
1082
+ inputStyles: {}, // Optional, styles that should be applied to the form element.
1083
+ labelStyles: {}, // Optional, styles that will be applied to the label of the collect element.
1084
+ errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the collect element.
1085
+ label: 'string', // Optional, label for the form element.
1086
+ placeholder: 'string', // Optional, placeholder for the form element.
1087
+ altText: 'string', // (DEPRECATED) string that acts as an initial value for the collect element.
1088
+ validations: [], // Optional, array of validation rules.
1089
+ }
1090
+
1091
+ const options = {
1092
+ required: false, // Optional, indicates whether the field is marked as required. Defaults to 'false'.
1093
+ enableCardIcon: true, // Optional, indicates whether card icon should be enabled (only applicable for CARD_NUMBER ElementType).
1094
+ format: String, // Optional, format for the element (only applicable currently for EXPIRATION_DATE ElementType).
1095
+ enableCopy: false, // Optional, enables the copy icon in collect and reveal elements to copy text to clipboard. Defaults to 'false').
1096
+ };
1097
+
1098
+ const element = container.create(composableElement, options);
1099
+ ```
1100
+
1101
+ ### Step 3: Mount Container to the DOM
1102
+
1103
+
1104
+ 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.
1105
+
1106
+ ```javascript
1107
+ <form>
1108
+ <div id="composableContainer"/>
1109
+ <br/>
1110
+ <div id="button-id"/>
1111
+ <button type="submit">Submit</button>
1112
+ </form>
1113
+ ```
1114
+ 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"`.
1115
+
1116
+ ```javacript
1117
+ container.mount('#composableContainer');
1118
+ ```
1119
+
1120
+ ### Step 4: Collect data from elements
1121
+
870
1122
 
1123
+ 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:
1124
+ - `tokens`: Whether or not tokens for the collected data are returned. Defaults to 'true'
1125
+ - `additionalFields`: Non-PCI elements data to insert into the vault, specified in the records object format.
1126
+ - `upsert`: To support upsert operations, the table containing the data and a column marked as unique in that table.
1127
+
1128
+ ```javascript
1129
+ const options = {
1130
+ tokens: true, // Optional, indicates whether tokens for the collected data should be returned. Defaults to 'true'.
1131
+ additionalFields: {
1132
+ records: [
1133
+ {
1134
+ table: 'string', // Table into which record should be inserted.
1135
+ fields: {
1136
+ column1: 'value', // Column names should match vault column names.
1137
+ // ...additional fields here.
1138
+ },
1139
+ },
1140
+ // ...additional records here.
1141
+ ],
1142
+ }, // Optional
1143
+ upsert: [ // Upsert operations support in the vault
1144
+ {
1145
+ table: 'string', // Table name
1146
+ column: 'value', // Unique column in the table
1147
+ },
1148
+ ], // Optional
1149
+ };
1150
+ ```
1151
+
1152
+ ### End to end example of collecting data with Composable Elements
1153
+
1154
+ ```javascript
1155
+ // Step 1
1156
+ const containerOptions = {
1157
+ layout: [2, 1],
1158
+ styles: {
1159
+ base: {
1160
+ border: '1px solid #eae8ee',
1161
+ padding: '10px 16px',
1162
+ borderRadius: '4px',
1163
+ margin: '12px 2px',
1164
+ },
1165
+ },
1166
+ errorTextStyles: {
1167
+ base: {
1168
+ color: 'red',
1169
+ },
1170
+ },
1171
+ };
1172
+
1173
+ const composableContainer = skyflow.container(
1174
+ Skyflow.ContainerType.COMPOSABLE,
1175
+ containerOptions
1176
+ );
1177
+
1178
+ // Step 2
1179
+
1180
+ const collectStylesOptions = {
1181
+ inputStyles: {
1182
+ base: {
1183
+ fontFamily: 'Inter',
1184
+ fontStyle: 'normal',
1185
+ fontWeight: 400,
1186
+ fontSize: '14px',
1187
+ lineHeight: '21px',
1188
+ width: '294px',
1189
+ },
1190
+ },
1191
+ labelStyles: {},
1192
+ errorTextStyles: {
1193
+ base: {},
1194
+ },
1195
+ };
1196
+
1197
+ const cardHolderNameElement = composableContainer.create({
1198
+ table: 'pii_fields',
1199
+ column: 'first_name',
1200
+ ...collectStylesOptions,
1201
+ placeholder: 'Cardholder Name',
1202
+ type: Skyflow.ElementType.CARDHOLDER_NAME,
1203
+ });
1204
+
1205
+ const cardNumberElement = composableContainer.create({
1206
+ table: 'pii_fields',
1207
+ column: 'card_number',
1208
+ ...collectStylesOptions,
1209
+ placeholder: 'Card Number',
1210
+ type: Skyflow.ElementType.CARD_NUMBER,
1211
+ });
1212
+
1213
+ const cvvElement = composableContainer.create({
1214
+ table: 'pii_fields',
1215
+ column: 'cvv',
1216
+ ...collectStylesOptions,
1217
+ placeholder: 'CVV',
1218
+ type: Skyflow.ElementType.CVV,
1219
+ });
1220
+
1221
+ // Step 3
1222
+ composableContainer.mount('#composableContainer'); // Assumes there is a div with id='#composableContainer' in the webpage.
1223
+
1224
+ // Step 4
1225
+ composableContainer.collect({
1226
+ tokens: true,
1227
+ });
1228
+ ```
1229
+ ### Sample Response:
1230
+
1231
+ ```javascript
1232
+ {
1233
+ "records": [
1234
+ {
1235
+ "table": "pii_fields",
1236
+ "fields": {
1237
+ "first_name": "63b5eeee-3624-493f-825e-137a9336f882",
1238
+ "card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
1239
+ "cvv": "7baf5bda-aa22-4587-a5c5-412f6f783a19",
1240
+ }
1241
+ }
1242
+ ]
1243
+ }
1244
+ ```
1245
+ For information on validations, see [validations](#validations).
1246
+
1247
+ ### Set an event listener on Composable Elements:
1248
+
1249
+ You can communicate with Skyflow Elements by listening to element events:
1250
+
1251
+ ```javascript
1252
+ element.on(Skyflow.EventName,handler:function)
1253
+ ```
1254
+
1255
+
1256
+ The SDK supports four events:
1257
+
1258
+ - `CHANGE`:riggered when the Element's value changes.
1259
+ - `READY`:riggered when the Element is fully rendered.
1260
+ - `FOCUS`: Triggered when the Element gains focus.
1261
+ - `BLUR`: Triggered when the Element loses focus.
1262
+
1263
+ 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:
1264
+
1265
+ ```javascript
1266
+ state : {
1267
+ elementType: Skyflow.ElementType
1268
+ isEmpty: boolean
1269
+ isFocused: boolean
1270
+ isValid: boolean
1271
+ value: string
1272
+ }
1273
+ ```
1274
+ `Note`: Events only include element values when in the state object when env is DEV. By default, value is an empty string.
1275
+
1276
+ ### Example Usage of Event Listener on Composable Elements
1277
+
1278
+ ```javascript
1279
+ const containerOptions = {
1280
+ layout: [1],
1281
+ styles: {
1282
+ base: {
1283
+ border: '1px solid #eae8ee',
1284
+ padding: '10px 16px',
1285
+ borderRadius: '4px',
1286
+ margin: '12px 2px',
1287
+ }
1288
+ },
1289
+ errorTextStyles: {
1290
+ base: {
1291
+ color: 'red'
1292
+ }
1293
+ }
1294
+ }
1295
+
1296
+ const composableContainer = skyflow.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
1297
+
1298
+ const cvv = composableContainer.create({
1299
+ table: 'pii_fields',
1300
+ column: 'primary_card.cvv',
1301
+ type: Skyflow.ElementType.CVV,
1302
+ });
1303
+
1304
+ composableContainer.mount('#cvvContainer');
1305
+
1306
+ // Subscribing to CHANGE event, which gets triggered when element changes.
1307
+ cvv.on(Skyflow.EventName.CHANGE, state => {
1308
+ // Your implementation when Change event occurs.
1309
+ console.log(state);
1310
+ });
1311
+ ```
1312
+
1313
+ Sample Element state object when env is `DEV`
1314
+
1315
+ ```javascript
1316
+ {
1317
+ elementType: 'CVV'
1318
+ isEmpty: false
1319
+ isFocused: true
1320
+ isValid: false
1321
+ value: '411'
1322
+ }
1323
+ ```
1324
+
1325
+ Sample Element state object when env is `PROD`
1326
+
1327
+ ```javascript
1328
+ {
1329
+ elementType: 'CVV'
1330
+ isEmpty: false
1331
+ isFocused: true
1332
+ isValid: false
1333
+ value: ''
1334
+ }
1335
+ ```
1336
+ ---
871
1337
  # Securely revealing data client-side
872
1338
  - [**Retrieving data from the vault**](#retrieving-data-from-the-vault)
873
1339
  - [**Using Skyflow Elements to reveal data**](#using-skyflow-elements-to-reveal-data)
@@ -887,10 +1353,13 @@ const records = {
887
1353
  records: [
888
1354
  {
889
1355
  token: 'string', // Token for the record to be fetched.
1356
+ redaction: RedactionType // Optional. Redaction to be applied for retrieved data.
890
1357
  },
891
1358
  ],
892
1359
  };
893
1360
 
1361
+ Note: If you do not provide a redaction type, RedactionType.PLAIN_TEXT is the default.
1362
+
894
1363
  skyflow.detokenize(records);
895
1364
  ```
896
1365
  An [example](https://github.com/skyflowapi/skyflow-js/blob/master/samples/using-script-tag/pure-js.html) of a detokenize call:
@@ -901,6 +1370,10 @@ skyflow.detokenize({
901
1370
  {
902
1371
  token: '131e70dc-6f76-4319-bdd3-96281e051051',
903
1372
  },
1373
+ {
1374
+ token: '1r434532-6f76-4319-bdd3-96281e051051',
1375
+ redaction: Skyflow.RedactionType.MASKED
1376
+ }
904
1377
  ],
905
1378
  });
906
1379
  ```
@@ -912,7 +1385,11 @@ The sample response:
912
1385
  {
913
1386
  "token": "131e70dc-6f76-4319-bdd3-96281e051051",
914
1387
  "value": "1990-01-01",
915
- }
1388
+ },
1389
+ {
1390
+ "token": "1r434532-6f76-4319-bdd3-96281e051051",
1391
+ "value": "xxxxxxer",
1392
+ }
916
1393
  ]
917
1394
  }
918
1395
  ```
@@ -1008,9 +1485,12 @@ const revealElement = {
1008
1485
  errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the reveal element.
1009
1486
  label: 'string', // Optional, label for the form element.
1010
1487
  altText: 'string', // Optional, string that is shown before reveal, will show token if altText is not provided.
1488
+ redaction: RedactionType, //Optional, Redaction Type to be applied to data, RedactionType.PLAIN_TEXT will be applied if not provided.
1011
1489
  };
1012
1490
  ```
1013
1491
 
1492
+ Note: If you don't provide a redaction type, RedactionType.PLAIN_TEXT will apply by default.
1493
+
1014
1494
  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 and `copyIcon` style object.
1015
1495
 
1016
1496
  An example of a inputStyles object:
@@ -1102,6 +1582,7 @@ const cardNumberElement = container.create({
1102
1582
  },
1103
1583
  label: 'card_number',
1104
1584
  altText: 'XXXX XXXX XXXX XXXX',
1585
+ redaction: SKyflow.RedactionType.MASKED
1105
1586
  });
1106
1587
 
1107
1588
  const cvvElement = container.create({
@@ -1115,9 +1596,20 @@ const cvvElement = container.create({
1115
1596
  altText: 'XXX',
1116
1597
  });
1117
1598
 
1599
+ const expiryDate= container.create({
1600
+ token: 'a4b24714-6a26-4256-b9d4-55ad69aa4047',
1601
+ inputStyles: {
1602
+ base: {
1603
+ color: '#1d1d1d',
1604
+ },
1605
+ },
1606
+ label: 'expiryDate',
1607
+ altText: 'MM/YYYY',
1608
+ });
1118
1609
  // Step 3.
1119
1610
  cardNumberElement.mount('#cardNumber'); // Assumes there is a placeholder div with id='cardNumber' on the page
1120
1611
  cvvElement.mount('#cvv'); // Assumes there is a placeholder div with id='cvv' on the page
1612
+ expiryDate.mount('#expiryDate'); // Assumes there is a placeholder div with id='expiryDate' on the page
1121
1613
 
1122
1614
  // Step 4.
1123
1615
  container
@@ -1137,9 +1629,14 @@ The response below shows that some tokens assigned to the reveal elements get re
1137
1629
  ```
1138
1630
  {
1139
1631
  "success": [
1140
- {
1141
- "token": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75"
1142
- }
1632
+ {
1633
+ "token": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
1634
+ "value": "xxxxxxxxx4163"
1635
+ },
1636
+ {
1637
+ "token": "a4b24714-6a26-4256-b9d4-55ad69aa4047",
1638
+ "value": "12/2098"
1639
+ }
1143
1640
  ],
1144
1641
  "errors": [
1145
1642
  {
@@ -1419,4 +1916,4 @@ container.uploadFiles();
1419
1916
 
1420
1917
  ## Reporting a Vulnerability
1421
1918
 
1422
- 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.
1919
+ 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.