GithubHelp home page GithubHelp logo

verygoodsecurity / vgs-collect-js Goto Github PK

View Code? Open in Web Editor NEW
7.0 18.0 14.0 782 KB

VGS Collect.js script loading module

Home Page: https://www.verygoodsecurity.com/

TypeScript 94.78% JavaScript 0.58% Python 1.21% Shell 3.43%
js javascript pci-dss pci collect tokenization vgs zerodata team-developer-experience

vgs-collect-js's Introduction

VGS Logo

VGS Collect.js

Script loading module for VGS Collect.js
Explore the docs »

Report Bug · Request Feature

CircleCI

Overview

What is VGS Collect.js?

VGS Collect.js is a JavaScript library that allows you to securely collect data via any form. Instantly create custom forms that adhere to PCI, HIPAA, GDPR, or CCPA security requirements. VGS intercepts sensitive data before it hits your servers and replaces it with aliased versions while securing the original data in our vault. The form fields behave like traditional forms while preventing access to the unsecured data by injecting secure iframe components.

Why do I need to use this package?

This module intended to simplify VGS Collect.js script loading process. To stay PCI Compliant it's a mandatory to load js from our js.verygoodvault.com domain as a consequence you need to find the best way to include our script, this small utility will solve the problem for you. You can still use the conventional way and just stick a reference to the script in the HEAD section of your page but you may lose some beneficial advantages the package provides:

  • Error handling
  • Fallback CDN managing
  • Reduced latency of cross-origin requests

Installation

Install the package using npm:

npm install @vgs/collect-js

How to use

The imported function inserts the <script> tag to the document head or body and returns the Collect instance as the result of resolved Promise. The script won't be loaded until loadVGSCollect() invoked. In order to speed up cross-domain loading, dns-prefetch and preconnect were added as a side effect.

import { loadVGSCollect } from '@vgs/collect-js';

// load script
const collect = await loadVGSCollect({
  vaultId: '<vault_id>', // required
  environment: '<environment>',
  version: '<x.x.x>'
}).catch((e) => {
  // script was not loaded
});

// https://www.verygoodsecurity.com/docs/vgs-collect/js/integration#form-state
const form = collect.init(state => { console.log(state); });

// https://www.verygoodsecurity.com/docs/vgs-collect/js/integration#create-and-setup-form-fields
form.field({...});
form.field({...});
form.field({...});

// https://www.verygoodsecurity.com/docs/vgs-collect/js/integration#setup-form-submission
form.submit(...);

or use Promise syntax as an alternative:

import { loadVGSCollect } from '@vgs/collect-js';

// load script
loadVGSCollect({
  vaultId: '<vault_id>', // required
  environment: '<environment>',
  version: '<x.x.x>'
})
  .then((collect) => {
    const form = collect.create(state => { console.log(state); });
  })
  .catch((e) => {
  // script was not loaded
});

loadVGSCollect(config)

Available properties:

Property Type Description Default
vaultId string Every VGS vault has a unique vault id - it’s a string value beginning with the prefix tnt. required
environment string Vault environment. Can be sandbox, live, or one with a specified data region (e.g live-eu-1). 'sandbox'
version string You can specify library version being loaded. Version must be >= 2.0. Please check our Changelog for more details. 'canary'

.init(callback)

A wrapper over original .create() method. As we have already received vault_id and environment from the loadVGSCollect() argument, there is no need to specify those params again. The method only returns the form state in the callback.You can still use .create() if necessary.

VGSCollect.init(state => { console.log(state); });

Documentation

Full abilities of VGS Collect.js and integration details you can find in our documentation.

CSP directives

We strongly recommend to add the CSP to your application. Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. Please create CSP directives for the following domains:

connect-src https://js.verygoodvault.com https://js3.verygoodvault.com https://vgs-collect-keeper.apps.verygood.systems frame-src https://js.verygoodvault.com https://js3.verygoodvault.com script-src https://js.verygoodvault.com https://js3.verygoodvault.com

Examples

Built with

Contact

If you have any questions please reach out to support or open issue here.

vgs-collect-js's People

Contributors

420neshot avatar annakudriasheva avatar dependabot[bot] avatar flor-master avatar huyb1991 avatar jentfoo avatar sanohin avatar tatimoli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vgs-collect-js's Issues

How to detect no response from iframe

Problem

Cannot detect error message no response from iframe:
Uncaught (in promise) Error: No response from iframe 'data.attributes.expirationDate' during 3000 ms.

Expected:

Have any way to detect this case? I want to show the error message on UI when getting this case.

How to catch long running HTTP requests to VGS?

Current Behavior

VGS currently has an active incident: https://status.verygoodsecurity.com/
image

This is causing inbound routes calling our VGS vault to have a long-running HTTP request (> 1min) and then fail.

Expected Behavior

VGS allows setting a timeout on submit calls for inbound routes and surfaces an error when the timeout is hit.

Your Environment

  • Version used: 2.18.1
  • Browser Name and version: Seen across multiple browsers, I am on Microsoft Edge Version 109.0.1518.78 (Official build) (arm64)
  • Operating System and version (desktop or mobile): Desktop, MacOS 13.0

Field Mask Function

Expected Behavior

Pass null for maskChar and object for formatChar per documentation.

Current Behavior

TypseScript states maskChar can only be a string and formatChar is a string not an object.

Steps to Reproduce (for bugs)

field.mask('999-99-9999', '*');
or
field.mask('XXXXX', null, {'X': '[0-9]'});

Context

Unable to use the mask function.

autoFocus does not work on mobile( device: IOS, browser: chrome, safari)

Expected Behavior

  • autoFocus does not work on mobile( device: IOS, browser: chrome, safari)
  • It works on desktop device

image
(it changes color but doesn't really focus)

Current Behavior

  • I use react and MUI(Material UI)
  • When I open Modal(Dialog) and wait for VGS Collect load fields
  • After load fields successful, it does not focus to first field(with autoFocus: true)

Possible Solution

Steps to Reproduce (for bugs)

Context

  • User need to click first field after vgs collect load

Your Environment

  • Version used: 2.19
  • Browser Name and version: Safari, Chrome
  • Operating System and version (desktop or mobile): IOS
  • Link to your project:

tempForm.field('#cc-cvv2', { type: 'card-security-code', name: CVV_FIELD_NAME, maxLength: 3, validations: ['required', 'validCardSecurityCode'], css: VGSInputCSS, classes, autoFocus: true, autoComplete: 'off', inputMode: 'numeric' });

How to use regex validation?

Hey there,

I'm trying to validate US zip code which is 5 digits. In the collectjs docs there isn't a min/max length field validator, I can easily write a regex that expect 5 digits exactly and the docs say there is regExp field validation but no example is given on how it works. Even your own form builder produces an error when "regExp" validator is selected for a new field:
https://forms.vgs.dev/

Uncaught (in promise) Error: Invalid validations: regExp

Can you provide a working example?

Fails with Next.js (SSR)

Expected Behavior

Should be able to use it with SSR.

Current Behavior

The app crashes with the following error:
Screen Shot 2021-09-09 at 1 50 31 PM

Possible Solution

Adding the following check solves the problem:
Screen Shot 2021-09-09 at 1 51 13 PM

Steps to Reproduce (for bugs)

  1. npm i @vgs/collect-js
  2. import { loadVGSCollect } from '@vgs/collect-js';
  3. Try to load the component and the app will crash

Context

Currently, it's unusable with Next.js (SSR)

Your Environment

Next.js (11.0)
MacOS
Chrome
@vgs/collect-js": "^0.4.0"

CVC/CVV field validation

We have a use-case when we need to ask our customers to confirm their card CVC/CVV code. For that we use card-security-code VGS field.

There is a small issue that in this case it’s impossible to perform proper validation - should CVC/CVV code be 3 or 4 digits for example.

We have card BIN available - is there a way to tell card-security-code field the card BIN so that proper validation could be performed?

Alternatively we could add a read-only card-number that would hold masked card number, but it's not clear whether there is a way to control whether this field will be submitted or not - it could be a good addition as well, depending on the use case.

inputMode should be configureable

Expected Behavior

When initializing a form field, VGS should expose the option to configure the inputMode of the field. For example, a PIN input would have a type of text, and an inputMode of numeric, so that a numeric keyboard is opened on mobile web across all platforms.

Current Behavior

The inputMode of a field is currently assumed based on the type of the field. Some fields have inputMode as numeric when hideValue is true, but when this is set to false, this gets removed from the input for most field types. The only field type where inputMode remains as numeric whether or not hideValue is true or false is the number type. But inputs with this type do not support things like maxLength which is needed to limit PIN inputs to 4 characters.

Prevent browser from saving password

This isn't a bug, but I was curious to get some feedback. I use VGS collect to collect a one-time pin from users. I would like to prevent the browser from prompting the user to save the pin as a "password". Does this library support a use-case like that?

Need validation for comparing 2 value must not be equal

Missing validation for compare 2 value must be different

compareValue(value, fieldProps, validationName, validationParams, globalValue) {
    const { field, function: fn } = validationParams;
    const valueToCompare = globalValue[field];

    const allowed = {
      match: () => valueToCompare === value,
      notMatch: () => valueToCompare !== value,
    };

    if (!Object.hasOwnProperty.call(allowed, fn)) {
      throw new CollectError(
        `compareValue function "${fn}" does not exist. Allowed: ${Object.keys(allowed).join(', ')}`
      );
    }
    return allowed[fn]();
  },

I want to update one more validation for 2 value must be not equal. Please help me to check a look and this. Thank you!

Taxpayer Identification Number

Expected Behavior

I would like to have an input field similar to SSN except it's the format of a TIN (XXX-XXXXXX).

Ideally I could pass to form.field a type="tin" and validations={['validTIN']}

Current Behavior

I can hide the value but the format is all numbers with dashes.

form.field("#tin", {
  type="text",
  maxLength: 9,
  inputMode: 'numeric',
  hideValue: true,
});
Screenshot 2024-07-25 at 11 33 57 AM

I can mask the value but then the value doesn't get hidden.

form.field("#tin", {
  type="text",
  inputMode: 'numeric',
  hideValue: true,
}).mask('999-999999', '*');
Screenshot 2024-07-25 at 11 35 16 AM Screenshot 2024-07-25 at 11 35 26 AM

Possible Solution

I could at least do this myself if hideValue: true worked when there is a mask.

Context

Building a form that takes in TIN instead of SSN. It works with no dash but not as clear if the dash was present while inputing.

Getting this error Uncaught TypeError: v is not a function at vgs-collect.js:5:129897 in version 2.12.0

Current Behavior

I am installing it in my vue Ui library, but it does not submit the input fields

Context

This has hindered me from submitting the form, it can certainly perform validation of the inputs fields but on submission it does not go through.

Your Environment

  • Version used: 2.12.0
  • Browser Name and version: Google Chrome
  • Operating System and version (desktop or mobile): Mac os (Big Sur)
  • Link to your project:

Remove card brand support?

Hello - I see in the documentation there is a way to add new card brands or redefine support for existing card brands. Is there a way to remove support for some card brands?

Thanks!

card-number validation issue with vgs-collect version update

Expected Behavior

Previously, we've been testing with 4242 4242 4242 4242 using the vgs collect version 2.15.0 and the validations in place in line with your documentation:

                   validations={['required', 'validCardNumber']}

This stopped the number at 16 chars max length.
Without changing code, and only by upgrading to vgs collect 2.22.0, we are now able to type in 3 extra chars.

Screenshot 2024-05-02 at 3 10 57 PM

If it's a 16-digit card, it should stop at 16 digits.

Current Behavior

I noticed in your test data documentation that the length of 19 is apparently accepted: https://www.verygoodsecurity.com/docs/vgs-collect/test-data

Sanity checked myself by trying out a Mastercard number that only allows 16 chars per your documentation table.
Screenshot 2024-05-02 at 3 12 19 PM

While it seems like per your documentation the length of 19 is expected for certain Visa cards, to us it's a bug because previously it stopped the 4242... card at 16 without allowing room for more characters to be typed in.

I don't know what happened between 2.15.0 and 2.22.0 to cause this. In the same way that you're able to deduce that the 2222 is a Mastercard number and stops at 16 digits, can the same not be done for certain Visa cards?

Possible Solution

If there isn't a way to determine by the first few numbers that it's a Visa success card, or whether it should be a 16- or 19-digit card, what is the best way to stop 16-digit cards from reaching extra 3 digits?

Steps to Reproduce (for bugs)

  1. Be on VGS Collect version 2.22.0
  2. Use validations validations: ['required', 'validCardNumber'], type: 'card-number
  3. Try standard Visa success test card 4242 4242 4242 4242 then see if you can type extra 424

Context

Your Environment

  • Version used: VGS 2.22.0 (bugged), 2.15.0 (was working)
  • Browser Name and version: Chrome Version 124.0.6367.91
  • Operating System and version (desktop or mobile): MacOS Ventura 13.4
  • Link to your project: sorry it's private.

Typescript definitions

Expected Behavior

Your type library does not cover most of the type definitions for the library itself. It would be great to add more.

Current Behavior

Typescript definitions are failing in my repository.

Possible Solution

import { IConfig } from '@vgs/collect-js/dist/utils/IConfig';

type stateParam = {
  errorMessages: string[];
  isDirty: boolean;
  isEmpty: boolean;
  isFocused: boolean;
  isTouched: boolean;
  isValid: boolean;
  name: string;
};

type responseData = {
  errors: {
    detail: string;
    source: {
      pointer: string;
    };
    status: string;
    title: string;
  }[];
};

declare module '@vgs/collect-js' {
  export interface VGSForm {
    field: (
      id: string,
      options: {
        type: string;
        name: string;
        placeholder: string;
        validations: string[];
        successColor?: string;
        errorColor?: string;
        maxLength?: number;
        yearLength?: number;
        serializers?: string[];
        css?: Record<string, string>;
      },
    ) => void;
    SERIALIZERS: string;
    submit: (
      path: string,
      options: {
        mapDotToObject: string;
        headers: Record<string, string>;
      },
      onResponse?: (status: number, data: responseData) => void,
    ) => void;
    state: Record<string, stateParam>;
    onUpdateCallback: unknown;
  }

  export interface CollectFN {
    init: (fn?: (state: Record<string, stateParam>) => void) => VGSFormDef;
  }

  export const loadVGSCollect: (config?: IConfig) => Promise<CollectFN>;
}

Context

Your Environment

  • Version used:
  • Browser Name and version:
  • Operating System and version (desktop or mobile):
  • Link to your project:

Bundle Size is large due to core-js inclusion

Expected Behavior

Most users do not need to support IE11. Either deprecate IE11 support, or include a modern build.

Current Behavior

This causes the bundle size to be large ... currently about 50KB (gzip size) of core-js polyfills are being included. If consumer does not need to support IE11, they do not need these polyfills

its not working in IE 11

Expected Behavior

Credit card field should render on UI.

Current Behavior

In IE 11, all fields from VGS iframe is not getting rendered and getting error
Unhandled promise rejection TypeError: Object doesn't support property or method 'append'
Unhandled promise rejection TypeError: Object doesn't support property or method 'init'

Possible Solution

Not sure if its issue from vgs or its from vgs-collect-js

Steps to Reproduce (for bugs)

Context

Your Environment

  • Version used:
  • Browser Name and version:
  • Operating System and version (desktop or mobile):
  • Link to your project:

Multiple Forms Initialization with VGSCollect

Expected Behavior

VGSCollect should allow specifying a unique form ID or a selector for each form initialization, enabling multiple forms to coexist on the same page without conflicts or duplication of fields and event listeners.

Current Behavior

Currently, VGSCollect requires forms to have an ID of "collect-form". When multiple forms with the same ID are present on the page, the first form is initialized multiple times, leading to duplicated fields and event listeners, the other forms are ignored. This not only causes a validation error in HTML but also results in improper handling of form data and events.

Possible Solution

  • Allow passing a form ID or CSS selector in the VGSCollect.create method to specify the scope of initialization.

Steps to Reproduce (for bugs)

  1. Create a page with multiple credit card forms.
  2. Ensure each form has the ID "collect-form".
  3. Initialize VGSCollect for each form using the current API.
  4. Observe that only the first form is initialized, but multiple times, resulting in field duplication and multiple event listeners being attached.

Context

We are integrating VGSCollect on a page with multiple tabs containing forms for adding or managing payment methods. The current limitation with form IDs causes significant issues, including HTML validation errors and improper handling of form interactions. This issue is critical as it affects the usability and security of the payment forms on our platform.

ERROR in node_modules/@vgs/collect-js/dist/index.d.ts:1:41 - error TS2304: Cannot find name 'IConfig'.

Expected Behavior

After installing the dependency my project should be able to compile

Current Behavior

After installing the vgs-collect-js package I try and build/run my Angular project.
I've got an Ionic Angular project and get the following error:

ERROR in node_modules/@vgs/collect-js/dist/index.d.ts:1:41 - error TS2304: Cannot find name 'IConfig'.
1 declare const loadVGSCollect: (config?: IConfig) => Promise<unknown>;

Possible Solution

Include the IConfig type in the package

Steps to Reproduce (for bugs)

  1. Install vgs-collect-js package
  2. run ionic serve (Ionic, Angular project)

Context

I'm trying to make use of this package but my project wont build or run locally due to the missing type

Your Environment

  • Version used: 0.3.0 (I also tried 0.2.0 but got the same error
  • Operating System and version (desktop or mobile): MacOS

Validate that 2 fields are not equal

Expected Behavior

  • I want to validate that 2 fields are not equal.

Context

  • I'm working with change PIN and need to validate new pin is not equal to the old pin
    ex: https://docs.unit.co/cards/#change-pin
  • Something like this
    validations: ['required', '/^([0-9]{4})$/', { type: 'compareValue', params: { field: PIN_FIELD_NAME, function: 'notMatch' } }],

isFocused property not getting updated on inputs of type "zip-code"

Expected Behavior

The isFocused property in the form state should get updated on focus and blur for vgs form fields of type zip-code

Current Behavior

isFocused does not get updated for zip-code inputs

Steps to Reproduce (for bugs)

Code pen example:
https://codepen.io/ali_ebner/pen/NWXBvjM?editors=1111

  1. Put your cursor into the zip code field or start typing into this field
  2. Check the output of the card-zip form state in the console. See that isFocused remains false even though other fields update
  3. Remove focus from the zip code field
  4. See that other form fields update but isFocused remains false/unchanged

Context

Styles and other behaviors that are dependent on the isFocused state for this field are not applying.
Current workaround is to use field.on('focus') and field.on('blur') and then update React state to keep track of focus for this field.

Your Environment

  • Version used: 2.12.0
  • Browser Name and version: Chrome 99.0.4844.74
  • Operating System and version (desktop or mobile): macOS Big Sur 11.6

Date Format

Expected Behavior

https://www.verygoodsecurity.com/docs/api/collect/#api-formfield
I would like to be able to change the format of the date that is redacted so that when I send it to a 3rd party I can reveal it in the format they are expecting. I would expect to set this in the serializer option.

Current Behavior

The date is always redacted and reveal in the "yyyy-mm-dd" format.

Possible Solution

To workaround I need to create custom Larky code in my outbound route:

def process(input, ctx):
    body = json.loads(str(input.body))

    applicantDob = vault.reveal(body['primaryApplicant']['dateOfBirth'])
    body['primaryApplicant']['dateOfBirth'] = reformatDate(applicantDob)

    input.body = builtins.bytes(json.dumps(body))
    return input

def reformatDate(date):
    return '/'.join((date[5:7], date[8:], date[:4]))

Steps to Reproduce (for bugs)

form.field('#space-for-my-field', {
  type: 'date',
  name: 'date-of-birth',
  validations: ['required'],
});

Context

I have 3rd party clients whose API only accepts date of birth in the format of 'mm/dd/yyyy'.

Your Environment

  • Version used: 2.18.6
  • Browser Name and version: All
  • Operating System and version (desktop or mobile): All
  • Link to your project: N/A

Validation Error Display

Expected Behavior

I shouldn't see any validation errors when the field is not dirty.
As I type input into the field the first time I shouldn't see a validation error.

Current Behavior

I see the validation error when I first type.

Possible Solution

Check if the field is dirty before firing the validation.

Steps to Reproduce (for bugs)

form.field('#space-for-my-field', {
type: 'ssn',
name: 'ssn',
validations: ['required', 'validSSN'],
});
Screenshot 2024-07-25 at 12 15 53 PM

Context

Just frustrating for users to get an error before completing the input.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.