Skip to content

Setup

There are two options to start a project:

  1. Using pre-built example projects that will fit into your solution framework.
  2. Following the instructions provided in section two.

1. List of projects examples by framework

Download the example that fits your needs

  1. Vue
  2. React
  3. Angular
  4. Lit Element

2. Manual integration

We provide a demo application that shows how to integrate and run the SDK. In this section, it is explained how to run the demo as well as how to use it and what contains.

Steps to launch Demo

  1. Download this zip file and then decompress it.

  2. Copy your own SDK files to the root of the demo folder.

  3. To run the demo, open a terminal in the extracted folder and run the following commands:

       npm i -g serve
       serve . --ssl-key=certs/key.pem --ssl-cert=certs/cert.pem
         ┌───────────────────────────────────────────────────┐
         │                                                   │
         │   Serving!                                        │
         │                                                   │
         │   - Local:            https://localhost:3000      │
         │   - On Your Network:  https://192.168.9.192:3000  │
         │                                                   │
         │   Copied local address to clipboard!              │
         │                                                   │
         └───────────────────────────────────────────────────┘
    
  4. Go to https://localhost:3000/demo, or the value which appeared in the - Local field above.

Files

In the demo folder you will find the following files and folders:

  • index.html The html to be launched.
  • setup.js This is the integration code that allow to launch the sdk.
  • config.json This is the file with all the sdk configuration.
  • assets SDK bundle and dependencies required by the SDK.
  • certs Self signed public key and private certificate to provide SSL on demo launch (visit next section Creating Self-Signed Certificate).

Note The files above are required for the demo to start properly. EDIT THEM CAREFULLY

Creating Self-Signed Certificate

To launch the demo without SSL warning you can create a self-signed certificate with the following command:

# openssl self-signed certificate 
openssl req -x509 \
            -sha256 -days 356 \
            -nodes \
            -newkey rsa:2048 \
            -subj "/CN=docs.veridas.com/C=ES/L=Pamplona" \
            -keyout rootCA.key -out rootCA.crt

Index.html

The index.html file loads the SDK package, while the setup.js script handles the loading and initiation of the SDK. It also creates a container where the SDK will be displayed.

This container must have a defined width and height for the sdk to be rendered correctly.

We recommend in mobile devices the size gets almost the full size of the viewport in order to avoid content overflows. This could be done using the following CSS rule "width: 100dvw, height:100dvh"

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <link rel="icon" type="image/x-icon" href="assets/images/veridasLogo.png" />
        <title>SDK Photo Selfie</title>
        <script type="module" defer src="assets/vd-selfie.umd.js"></script>
        <script src="setup.js"></script>
    </head>
    <body>
        <div id="demoContainer" style="width:100dvw; height: 100dvh"></div>
    </body>
</html>

Configuration input

When initializing the SDK, you can configure and customize the SDK. That way, you can provide a more personalized approach.

You can set its configuration, with the initializeSdk function. This function supports two types of configuration:

  • Config by File: You can set the configuration, passing the path to your configuration file (config.json), exposed on your server. For example:
    VDSelfie.initializeSdk("./config.json", aliveChallenge)
  • Config by Object: You can also set the configuration, passing an config object to the initializeSdk function. For example:
const configObject = {
    ...
    sdkSelfie: {
        flowType: "head",
    },
    ...
}
VDSelfie.initializeSdk(configObject, aliveChallenge)

This config object needs to follow the correct schema.

Although it is not longer necessary, you have to take into account that in the SDK Selfie SAP in production, you will have to pass a valid token to do the validation. The token, also refered here as aliveChallenge, can be passed through the configuration file(config.json) or object(configObject) as saw in the examples above. If you want to know more about how you can add the challenge token via configuration check the captureHeadToken section in the SDK Selfie Configuration table.

You can get more details about the configuration when starting the SDK, go to the Initialize SDK section of this method documentation.

Also, one of the important properties to set up is the pathAssets. This is used to indicate the location to the assets folder and it is explained in the following section.

Property sdkSelfie.pathAssets

This important property is used by the SDK to load internal assets. You can check it's default value in our SDK Selfie Configuration table.

To add the pathAssets property correctly, you can do it in two different ways:

  • Absolute path: indicating the full path to the assets folder
  • Relative path: indicating the relative path from the location of the sdk to the folder

If the assets folder is not a descendant of the sdk folder, you can use the ../ relative path to descend folders from the main sdk path or use an absolute path to indicate its location.

Property sdkSelfie.flowType

An important and recommended property you might consider configuring is flowType. By default, it's set to head. This property sets the type of flow the SDK will take. Depending on your use case, you might find one flow more suited than the others.

The available options for flowType are:

  • selfie: This flow is used purely for capturing the user's face. No additional user actions are required.
  • head: This is an advanced feature in the 'Selfie Alive Pro' flow. It prompts the user with specific instructions on head movement that they need to follow to complete the flow.

For example, if you would like to use the 'Selfie' flow, you can include the following in your configuration:

const optionalConfigObject = {
    ...
    sdkSelfie: {
        flowType: "head",
    },
    ...
}

Here is an example of a configuration file with optional configuration parameters:

{
    "$schema": "./assets/schema.json",
    "sdkSelfie": {
        "flowType": "selfie",
        "pathAssets": "assets",
        "views": {
            "deviceRotated": {
                "active": true
            },
            "capture": {
                "head": {
                    "arrows": {
                        "arrowTop": "/images/topArrow.svg",
                        "arrowRight": "/images/rightArrow.svg",
                        "arrowBottom": "/images/bottomArrow.svg",
                        "arrowLeft": "/images/leftArrow.svg"
                    }
                }
            },
            "instructions": {
                "active": false
            },
            "reviewImage": {
                "active": true
            }
        }
    },
    "generic": {
        "theme": {},
        "common": {
            "ui": {
                "buttons": {
                    "close": {
                        "show": true
                    }
                }
            }
        }
    }
}

Here is an example of a configuration object with optional configuration parameters:

const optionalConfigObject = {
    generic: {
        theme: {
            colorAlertError: "#d63737",
            colorAlertSuccess: "#AEE4C1",
            colorAlertSuccessDark: "#53A335",
            colorNeutral00: "#ffffff",
            colorNeutral05: "#f2f2f2",
            colorNeutral20: "#cccccc",
            colorNeutral40: "#999999",
            colorNeutral80: '#333333',
            colorPrimaryDark: "#000D44",
            colorPrimaryMain: "#257CD0",
            colorPrimaryLight: "#528bb8",
            radiusSm: "8px",
            shadowSm: "0px 4px 8px rgba(0, 0, 0, 0.25)",
            typographyBodyNormalFontFamily: "PublicSansNormal",
            typographyBodyRegularFontFamily: "PublicSansRegular",
        },
        common: {
            ui: {
                logo: { show: true, media: "veridasLogo.png" },
                buttons: {
                    close: {
                        "show": false,
                        "media": "/images/closeButton.svg"
                    }
                }
            },
            behavior: {
                web: {
                    logEvents: true,
                    language: "browser"
                },
            },
        },
    },
    sdkSelfie: {
        flowType: "head",
        pathAssets: "assets"
    },
}

This optional configuration object can be passed while initializing the SDK. If not provided, the SDK will use its default settings.

Moreover, it's not mandatory to provide all the configuration parameters suggested in the above example. You can selectively pass only certain configurations. For any parameters not explicitly specified, the SDK will seamlessly utilize the corresponding default settings.

Typography load

For the proper configuration of the default User Interface (UI) theme provided by Veridas, the SDK will automatically load two fonts, PublicSansNormal and PublicSansRegular if no other font is specified in the typographyBodyNormalFontFamily and typographyBodyRegularFontFamily fields of the theme section in the configuration object. Both fonts are included in the distribution and can be found in the assets/fonts folder.

If other fonts are specified in the configuration, those fonts must be loaded properly if they are not supported natively by the browser. The following example shows the style rules for loading the PublicSansNormal font, both by file and by URL:

@font-face {
    font-family: PublicSansNormal;
    src: url(./assets/fonts/PublicSansNormal.ttf);
}
@font-face {
    font-family: PublicSansNormal;
    src: url(https://fonts.googleapis.com/css2?family=PublicSansNormal:ital,wght@1,500&display=swap);
}

NOTE: if the PublicSans fonts are not loaded, then the default font will be Arial so the UI will not resemble the Veridas default theme.

SDK Loader

The demo project will load the SDK after the window.onload event is dispatched, and the SDK tag vd-selfie is settled in the DOM. An example of this can be seen in the following code:

Note that this function instantiates the SDK in the DOM but does not start it.

let VDSelfie, SdkEvents, isConfigByFile, demoContainer

window.onload = () => loadSDK()
function loadSDK() {
    SdkEvents = window.vdSelfie.VDSelfie.events
    demoContainer = document.querySelector('#demoContainer')
    demoContainer.innerHTML = "<vd-selfie></vd-selfie>"
    addListeners()
}

Events listener

The SDK triggers custom events so you can listen to them and execute certain logic. Check the api section for more information.

Let's see an example of three events very important for the operation of the SDK:

  • VD_mounted: (Legacy VDAlive_mounted) Before you can use the public method initializeSdk to load the configuration and initialize the detecting and capturing process, the SDK must be fully loaded into memory. This event indicates that the SDK is now fully operational and waiting to be initialized. This is when you can call the initializeSdk method to start the SDK. See api section for more information on SDK methods.
  • VD_restartProcess: (Legacy VDAlive_restartClicked) When for some reason, the detection process fails and needs to be repeated, the SDK emits this event to indicate that the detection process is going to be restarted. In the case of the head flow, is necessary to generate a new random challenge.
  • VD_capture: (Legacy VDAlive_faceDetection) Finally, when the detection process ends correctly, the SDK emits this event with the output data in its detail.

Here is the code for catching the SDK events and initialize the SDK. You should put this in your setup file:

/**
 * @name eventHandlers
 * @description Object with the event handlers for the SDK events
 * @type {Object}
 */
const eventHandlers = {
    VD_mounted: onSDKMounted, // Same as legacy event VDAlive_mounted
    VD_restartProcess: handleRestartProcess, // Same as legacy event VDAlive_restartClicked
    VD_capture: onSDKResult // Same as legacy event VDAlive_faceDetection
}

/**
 * @name handleEvent
 * @description Handles the SDK events for the events in the eventHandlers object
 * @param {Object} e Event object
 * @returns {void}
 */
function handleEvent(e) {
    const handler = eventHandlers[e.type]
    if (handler) {
        handler(e)
    }
}

/**
 * @name addListeners
 * @description Adds the event listeners for the SDK events in the `SdkEvents` array
 */
function addListeners() {
    SdkEvents.forEach(sdkEvent => {
        addEventListener(sdkEvent, e => {
            handleEvent(e)
        })
    })
}

Initialize

Once the VDAlive_mounted SDK event is dispatched, the function responsible for launching the SDK is invoked. This function can utilize an optional configuration, either defined within a file or an object.

Additionally, it's noteworthy that the aliveChallenge parameter is not necessary during the SDK initialization. If no value is inserted into this property, the default value will be available for testing or debugging purposes via the browser console. However it should never be used in a production environment. This parameter must be set with a valid token obtained from the Validas API.

This is illustrated in the example below.

async function launchSDK() {
    VDSelfie = document.querySelector("vd-selfie")
    // Use getJWTChallenge only for development purpose, never in production mode
    const aliveChallenge = VDSelfie.getJWTChallenge() 
    if (isConfigByFile) {
        await VDSelfie.initializeSdk('./config.json', aliveChallenge)
    } else if (configObject) {
        await VDSelfie.initializeSdk(configObject, aliveChallenge)
    } else {
        // This uses the configuration with the default values defined in the SDK Configuration
        await VDSelfie.initializeSdk(null, aliveChallenge)
    }
}

In the above example, the SDK can be initialized with a configuration (from a file or an object). If no configuration is provided, the SDK will utilize default settings.

In any scenario, the use of aliveChallenge is strongly recommended, since the SDK can provide a default token but this must not be used for production environments. The token must be requested from the Validas API.

Restart process

When the detection process fails and needs to be repeated, the SDK emits VD_restartProcess event to indicate that the detection process is going to be restarted. In the case of the head flow, is necessary to generate a new random challenge:

/**
 * @name handleRestartProcess
 * @description Event handler for the SDK restartProcess event to restart the process with the alive challenge token. If the code is 8000, 8001 or 8002, the alive challenge token is updated with the new one.
 * 8000 is for the challenge invalid head token.
 * 8001 is for the error in the challenge.
 * 8002 is for deviced rotated detection.
 */
function handleRestartProcess(e) {
    if ([8000, 8001, 8002].includes(e.detail.code)) {
        const aliveChallenge = VDSelfie.getJWTChallenge(useLongChallenge)
        VDSelfie.restartChallenge(aliveChallenge)
    }
}

Output Files

Finally, when the detection process ends correctly, the SDK emits VD_capture event with the output data in its detail.

In case of launching the Selfie flow, the output files are:

  • image: base64 image selfie.
  • webVTT: null.

In case of launching the Head flow, the output files are:

  • image: base64 image selfie before the challenge movements.
  • webVTT: contains the data of the WebVTT file.
  • image_alive: contains the data of the video captured in the head flow.
  • There's only one type of return possible:

    - Standard Output: video → Blob type. Contains the recorded video in webm format except for safari browser versions >= 14.8 which is in mp4 format.

      ![VDSelfieCustomizeElementsMap10](./images/VDSelfieImagen10.png)
    

Challenge Tokens Management

In order to determine the specific challenges that users must overcome for authentication, our SDK utilizes tokens. These tokens serve as indicators for the type of challenge the user needs to complete, such as looking upwards, looking sideways, and so on. The tokens are essential for the authentication flow and are required for various operations within our SDK.

Generating Tokens

To generate the challenge tokens, you should make a request to the Validas API. This API generates the appropriate tokens based on the desired challenge type. However, during development, we also provide the capability to generate tokens locally for testing purposes. It is important to note that these locally generated tokens should never be used in production environments.

Token Usage

When using our SDK, it is crucial to provide the required challenge token when the flowType of the sdkSelfie is head. This token is optional when included in the configuration object or file. However, it must be provided in one of these forms. If you are in development mode, you can alternatively pass the token via the aliveChallenge function parameter, making it unnecessary to include it in the configuration object or file specifically for this case.

If a token is not provided and you are in production mode, an error will occur. In such cases, we display a console error message that explains the issue and provides guidance on how to use the configuration or method with a token example. Additionally, it is important to emphasize that in production environments, a valid production-ready token must be obtained from the Validas API.

To acquire a production-ready token, please refer to the Validas API documentation, which contains the necessary information and guidelines for obtaining the appropriate token.

Remember, tokens are essential for the proper functioning of our SDK and are instrumental in ensuring secure and accurate biometric authentication through video integration.

Basic setup.js file

This is how we suggest your setup.js file should look like at the end:

let VDSelfie, SdkEvents, isConfigByFile, demoContainer

window.onload = () => loadSDK()

function loadSDK() {
    SdkEvents = window.vdSelfie.VDSelfie.events
    demoContainer = document.querySelector('#demoContainer')
    demoContainer.innerHTML = "<vd-selfie></vd-selfie>"
    addListeners()
}

/**
 * @name eventHandlers
 * @description Object with the event handlers for the SDK events
 * @type {Object}
 */
const eventHandlers = {
    VD_mounted: onSDKMounted, // Same as legacy event VDAlive_mounted
    VD_restartProcess: handleRestartProcess, // Same as legacy event VDAlive_restartClicked
    VD_capture: onSDKResult // Same as legacy event VDAlive_faceDetection
}

/**
 * @name handleEvent
 * @description Handles the SDK events for the events in the eventHandlers object
 * @param {Object} e Event object
 * @returns {void}
 */
function handleEvent(e) {
    const handler = eventHandlers[e.type]
    if (handler) {
        handler(e)
    }
}

/**
 * @name addListeners
 * @description Adds the event listeners for the SDK events in the `SdkEvents` array
 */
function addListeners() {
    SdkEvents.forEach(sdkEvent => {
        addEventListener(sdkEvent, e => {
            handleEvent(e)
        })
    })
}

/**
 * @name handleRestartProcess
 * @description Event handler for the SDK restartProcess event to restart the process with the alive challenge token. If the code is 8000, 8001 or 8002, the alive challenge token is updated with the new one.
 * 8000 is for the challenge invalid head token.
 * 8001 is for the error in the challenge.
 * 8002 is for deviced rotated detection.
 */
function handleRestartProcess(e) {
    if ([8000, 8001, 8002].includes(e.detail.code)) {
        const aliveChallenge = VDSelfie.getJWTChallenge(useLongChallenge)
        VDSelfie.restartChallenge(aliveChallenge)
    }
}

async function launchSDK() {
    VDSelfie = document.querySelector("vd-selfie")
    // Use getJWTChallenge only for development purpose, never in production mode
    const aliveChallenge = VDSelfie.getJWTChallenge()
    if (isConfigByFile) {
        await VDSelfie.initializeSdk('./config.json', aliveChallenge)
    } else if (configObject) {
        await VDSelfie.initializeSdk(configObject, aliveChallenge)
    } else {
        // This uses the configuration with the default values defined in the SDK Configuration
        await VDSelfie.initializeSdk(null, aliveChallenge)
    }
}