Skip to content

Commit

Permalink
Merge pull request #325 from lyra/KJS-3329
Browse files Browse the repository at this point in the history
fix(loadLibrary): fix loadLibrary domain validation
  • Loading branch information
s-yagues authored Nov 15, 2023
2 parents 42dcdcc + 07ce515 commit 5db6547
Show file tree
Hide file tree
Showing 19 changed files with 1,993 additions and 195 deletions.
16 changes: 14 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: E2E Tests
name: Tests
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
test:
test-e2e:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
Expand All @@ -30,3 +30,15 @@ jobs:
name: playwright-report
path: playwright-report/
retention-days: 30
test-unit:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Run unit tests
run: npm run test:unit
82 changes: 45 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!-- BACK TO TOP LINK -->
<a id="readme-top"></a>

<a id="readme-top"></a>

<!-- PROJECT SHIELDS -->
<div align="center">
Expand Down Expand Up @@ -37,21 +37,20 @@
</p>
</div>


![SmartForm](./assets/smartform.png)

## About the project

Any payment form must comply with PCI-DSS requirements. A classical integration will be displayed
on the banks page using a redirection. In that case, PCI-DSS requirements are done by your bank.

By using this package Lyra allows to integrate a payment form using standard HTML elements on your
website. This library will load the [Javacript library][doc-home] from Lyra servers transforming
automatically each sensitive field (pan, security code, ...) into an IFrame, allowing to comply with
By using this package Lyra allows to integrate a payment form using standard HTML elements on your
website. This library will load the [Javacript library][doc-home] from Lyra servers transforming
automatically each sensitive field (pan, security code, ...) into an IFrame, allowing to comply with
all regulations.

The **embedded-form-glue** library provides a set of utilities to easily integrate the Payment
form into any we application made with Javascript frameworks like React, Vue, Angular, Svelte,
The **embedded-form-glue** library provides a set of utilities to easily integrate the Payment
form into any we application made with Javascript frameworks like React, Vue, Angular, Svelte,
Ionic, etc.

## Getting Started
Expand All @@ -77,15 +76,17 @@ First, define the theme files to load in the head section of your HTML page:
```html
<head>
(...)
<link rel="stylesheet"
href="~~CHANGE_ME_ENDPOINT~~/static/js/krypton-client/V4.0/ext/neon-reset.css">
<link
rel="stylesheet"
href="~~CHANGE_ME_ENDPOINT~~/static/js/krypton-client/V4.0/ext/neon-reset.css"
/>
<script src="~~CHANGE_ME_ENDPOINT~~/static/js/krypton-client/V4.0/ext/neon.js"></script>
(...)
</head>
```

> **Note**
>
>
> Replace **`~~CHANGE_ME_ENDPOINT~~`** with your configuration endpoint.
For more information about theming, please see [Lyra theming documentation][doc-themes]
Expand All @@ -101,45 +102,44 @@ After that, define the location where the payment form will be generated in your
```

> **Note**
>
> Specifify the element **kr-smart-form** inside the target location to load the Smart Form (any
>
> Specifify the element **kr-smart-form** inside the target location to load the Smart Form (any
> kind of payment method).
### Javascript

Import the library in your javascript file or component with:

```javascript
import KRGlue from "@lyracom/embedded-form-glue";
import KRGlue from '@lyracom/embedded-form-glue'
```

And finally, you can generate the payment form with the following code:

```javascript
/* Integration public key */
const publicKey = '~~CHANGE_ME_PUBLIC_KEY~~';
/* Endpoint. Must include the protocol (https://) */
const endPoint = '~~CHANGE_ME_ENDPOINT~~';
const publicKey = '~~CHANGE_ME_PUBLIC_KEY~~'
/* Endpoint. Base domain with its protocol (e.g. https://domain.name, do not include any path after the domain) */
const endPoint = '~~CHANGE_ME_ENDPOINT~~'

/* Load the remote library and get the KR object */
const { KR } = await KRGlue.loadLibrary(endPoint, publicKey)
const { KR } = await KRGlue.loadLibrary(endPoint, publicKey)
/* Setting configuration */
await KR.setFormConfig({ 'kr-language': 'en-US' })
/* Attach a payment form to a given DOM selector */
const { result } = await KR.attachForm('#myPaymentForm')
/* Show the payment form */
await KR.showForm(result.formId);
/* Render the payment form into a given DOM selector */
await KR.renderElements('#myPaymentForm')
```

> **Note**
>
>
> Replace **`~~CHANGE_ME_PUBLIC_KEY~~`** with your configuration public key.
>
>
> Replace **`~~CHANGE_ME_ENDPOINT~~`** with your configuration endpoint.
> **Warning**
>
> KR methods use Promises. You should always use the **await** keyword or **then method** when
> calling them. Please see [Javascript Promises][js-promises] and [Async Functions][js-async-await]
>
> KR methods use Promises. You should always use the **await** keyword or **then method** when
> calling them. Please see [Javascript Promises][js-promises] and [Async Functions][js-async-await]
> for more information.
## First transaction
Expand All @@ -148,8 +148,8 @@ Once the payment form is set up, you will see the skeleton animation. This is be
using the default demo token. To make a real transaction, you need to get a real **formToken**.

To get a proper test **formToken**, make a request to the Charge/CreatePayment web service. To not
expose your credentials, it is mandatory to do that from a server. Please see the
[NodeJS server example](examples/server/README.md), or visit the following links for more
expose your credentials, it is mandatory to do that from a server. Please see the
[NodeJS server example](examples/server/README.md), or visit the following links for more
information:

- [Embedded form quick start][doc-quick-start]
Expand All @@ -160,10 +160,14 @@ Once you have a **formToken**, you can set it in the payment form with the follo

```javascript
// Use the loadLibrary to set the form token
const { KR } = await KRGlue.loadLibrary(endPoint, publicKey, '~~CHANGE_ME_FORM_TOKEN~~')
const { KR } = await KRGlue.loadLibrary(
endPoint,
publicKey,
'~~CHANGE_ME_FORM_TOKEN~~'
)

// Or set the form token once the library is loaded
const { KR } = await KRGlue.loadLibrary(endPoint, publicKey)
const { KR } = await KRGlue.loadLibrary(endPoint, publicKey)
await KR.setFormConfig({ formToken: '~~CHANGE_ME_FORM_TOKEN~~' })
```

Expand All @@ -178,11 +182,11 @@ methods.

### loadLibrary

Use `loadLibrary` method to load the Lyra Javascript library. The method returns a `Promise` with
Use `loadLibrary` method to load the Lyra Javascript library. The method returns a `Promise` with
the `KR` object.

```javascript
const { KR } = await KRGlue.loadLibrary(endPoint, publicKey)
const { KR } = await KRGlue.loadLibrary(endPoint, publicKey)
```

## KR object
Expand All @@ -195,7 +199,7 @@ The available methods and callbacks are described in the following sections.
- [KR callbacks](./docs/kr_callbacks.md)

> **Note**
>
>
> See Lyra [Javascript library reference][doc-reference] for the complete reference guide.
## JavaScript frameworks integration
Expand All @@ -221,14 +225,15 @@ The payment form can be customized in many ways. Some of them in the following e
- [Add additional fields](./docs/customization#add-additional-fields)
- [Use a different HTML structure](./docs/customization#use-a-different-html-structure)

Any of these customizations can be done using the same method **KR.attachForm()**.
Any of these customizations can be done using the same method **KR.renderElements()**.

> **Note**
>
> Please see the [Field Customization][doc-customization] section of the documentation for more
>
> Please see the [Field Customization][doc-customization] section of the documentation for more
> information.
<!-- CONTRIBUTING -->

## Contributing

Contributions are welcome and pull requests will be reviewed and taken into account.
Expand Down Expand Up @@ -260,17 +265,19 @@ npm run examples:serve
Execute the tests with the command:

```bash
npm run test
npm run test:e2e
```

<!-- LICENSE -->

## License

Distributed under the MIT License. See the [LICENSE file](./LICENCE.txt) for more information.

<p align="right">(<a href="#readme-top">back to top</a>)</p>

<!-- MARKDOWN LINKS & IMAGES -->

[build-shield]: https://img.shields.io/circleci/build/github/lyra/embedded-form-glue?style=for-the-badge&logo=github
[build-url]: https://circleci.com/gh/lyra/embedded-form-glue
[npm-shield]: https://img.shields.io/npm/v/@lyracom/embedded-form-glue?style=for-the-badge&logo=npm
Expand All @@ -285,6 +292,7 @@ Distributed under the MIT License. See the [LICENSE file](./LICENCE.txt) for mor
[license-url]: https://github.com/lyra/embedded-form-glue/blob/master/LICENSE.txt

<!-- DOC LINKS -->

[doc-home]: https://docs.lyra.com/en/rest/V4.0/javascript/
[doc-quick-start]: https://docs.lyra.com/en/rest/V4.0/javascript/quick_start_js.html
[doc-reference]: https://docs.lyra.com/en/rest/V4.0/javascript/features/reference.html
Expand Down
14 changes: 11 additions & 3 deletions app/KryptonGlue.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,23 @@ class Glue {
}

loadLibrary(domain, publicKey, formToken = null) {
const domainRegex =
/^(?:http(s)?:\/\/)[\w.-]+(?:\.[\w.-]+)+[\w\-._~:/?#[\]@!$&'()*+,;=.]+$/g
const pubKeyRegex = /^\d{2,8}:(|test)publickey_.+$/g

if (this.loaded) return this.getKrypton(publicKey)
if (!domain) return Promise.reject('Domain not defined')
if (!publicKey) return Promise.reject('Public key not defined')

if (!domainRegex.test(domain)) {
// Domain validation
try {
const domainUrl = new URL(domain)

if (!['http:', 'https:'].includes(domainUrl.protocol))
throw new Error('Invalid protocol')

if (domainUrl.port) throw new Error('No port allowed')
if (domainUrl.search !== '') throw new Error('No query params allowed')
if (domainUrl.pathname !== '/') throw new Error('Invalid path')
} catch (err) {
console.error('Domain format should be https://domain.name')
return Promise.reject(`[${domain}] is not a valid endpoint domain`)
}
Expand Down
14 changes: 7 additions & 7 deletions docs/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The payment form can be customized in many ways like:
<div class="kr-pan"></div>
<div class="kr-expiry"></div>
</div>
</div>
</div>
</div>
```

Expand All @@ -23,7 +23,7 @@ The payment form can be customized in many ways like:
<div class="kr-smart-form">
<div class="kr-embedded">
<div class="kr-pan"></div>
<input
<input
class="kr-theme my-custom-email-field"
type="text"
name="email"
Expand Down Expand Up @@ -57,13 +57,13 @@ The payment form can be customized in many ways like:
</div>
<div class="kr-expiry"></div>
</div>
</div>
</div>
</div>
```

Any of these customizations can be done using the same method **KR.attachForm()**.
Any of these customizations can be done using the same method **KR.renderElements()**.

> **Note**
>
> Please see the [Field Customization][doc-customization] section of the documentation for more
> information.
>
> Please see the [Field Customization][doc-customization] section of the documentation for more
> information.
25 changes: 18 additions & 7 deletions docs/kr_methods.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@

# KR object methods

These are the current available methods to manipulate the payment form:

## attachForm
## renderElements

Render a payment form into a given DOM selector: return a `promise` with the `KR` object and result.

```javascript
const selector = `#myPaymentForm` // DOM selector
const { KR, result } = await KR.renderElements(selector)
```

> **_NOTE:_** if nothing is provided renderElements will search the complete DOM for the supported HTML elements
## attachForm (DEPRECATED use renderElements instead)

Attach a payment form to a given DOM selector: return a `promise` with the `KR` object and result.

Expand All @@ -20,8 +30,9 @@ Add a payment form to a given DOM selector: return a `promise` with the `KR` obj
const selector = `#myPaymentForm` // DOM selector
const { KR, result } = await KR.addForm(selector)
```

> **Warning**
>
>
> Only for cards payment method
## showForm
Expand All @@ -42,7 +53,6 @@ const { result } = await KR.addForm(selector)
const { KR } = await KR.hideForm(result.formId)
```


## setFormConfig

Set the configuration of the payment form on runtime: return a `promise` with the `KR` object.
Expand All @@ -53,8 +63,9 @@ const { KR } = await KR.setFormConfig({
language: `en-US`
})
```

> **Note**
>
>
> Please see the [type definition](../index.d.ts) file for the list of available configuration options.
## validateForm
Expand Down Expand Up @@ -87,7 +98,6 @@ available in the payment form.
const { KR } = await KR.openPaymentMethod('cards')
```


## openPopin

On popin mode, open the payment form in a popin: return a `promise` with the `KR` object.
Expand Down Expand Up @@ -159,10 +169,11 @@ Remove all generated payment forms: return a `promise` with the `KR` object.
```javascript
const { KR } = await KR.removeForms()
```

## removeEventCallbacks

Remove all event callbacks: return a `promise` with the `KR` object.

```javascript
const { KR } = await KR.removeEventCallbacks()
```
```
Loading

0 comments on commit 5db6547

Please sign in to comment.