Supported Languages

Prove provides client web SDKs in the following languages: TypeScript and JavaScript.

Installation

The Prove Platform Web SDK has an unpacked size of 171 kB, and a single dependency: @prove-identity/mobile-auth. Install the client-side SDK of your choice by running a command in your terminal, or by using a dependency management tool specific to your project.

# Run this command to install the package (ensure you have the latest version).
npm install @prove-identity/prove-auth@2.8.2

Determine the Type of Flow: Mobile or Desktop

You can determine if the customer is on a mobile or desktop browser using this example. If the isMobile is true, pass mobile to the Start() function on the server, otherwise you can pass desktop:

// Check if the customer is on a mobile or desktop browser.
const authCheck = new proveAuth.AuthenticatorBuilder().build();
let isMobile = authCheck.isMobileWeb()

In a mobile flow, one-time password (OTP) validation is performed on the mobile phone. In a desktop flow, Instant Link sends a text message to the mobile phone for verification.

In the mobile flow, once the OTP validation completes, the AuthFinishStep function finishes.

In the desktop flow, a WebSocket opens for two minutes on the desktop browser while waiting for the customer to select on the link in the text message. Once clicked, the WebSocket closes and the AuthFinishStep function finishes.

Instant Link

If you’re using Content Security Policy headers, ensure you allow wss: device.uat.prove-auth.proveapis.com and wss: device.prove-auth.proveapis.com.

Authenticate()

The SDK requires an authToken as a parameter for the Authenticate() function. This token returns from the Start() call of the server-side SDK. The token is session specific, limiting it to a single flow. It also expires after 15 minutes.

Retrieve authToken

You need to send a request to your back end server with the possession type, and an optional phone number if you are using Prove’s possession check.

async function initialize(phoneNumber, possessionType) {
  const response = await fetch(backendUrl + "/initialize", {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      phoneNumber: phoneNumber,
      possessionType: possessionType,
    }),
  });

  const rsp = await response.json();
  const authToken = rsp.authToken;

  return authToken;
}

Setup Authenticator

Once you have the authToken, build the authenticator for both the mobile and desktop flows.

async function authenticate(isMobileWeb, authToken) {
  // Set up the authenticator for either mobile or desktop flow.
  let builder = new proveAuth.AuthenticatorBuilder();

  if (isMobileWeb) {
    // Set up OTP.
    builder = builder
      .withAuthFinishStep((input) => verify(input.authId))
      .withOtpFallback(otpStart, otpFinish);
  } else {
    // Set up Instant Link.
    builder = builder
      .withAuthFinishStep((input) => verify(input.authId))
      .withInstantLinkFallback(instantLink)
      .withRole("secondary");
  }

  const authenticator = builder.build();

  // Authenticate with the authToken.
  return authenticator.authenticate(authToken);
}

Validate the Mobile Phone

In the AuthFinishStep, you’ll specify a function to call once the possession checks complete on the mobile phone. This endpoint on your back end server calls the Unify-Status() function to validate the phone number. The AuthFinishStep then completes. In the event of cancellation, the server makes a call to the Unify-Status() function and returns success=false.

// Send a verify request.
async function verify() {
  const response = await fetch(backendUrl + "/verify", {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({}),
  });

  const results = await response.json();
  const rsp = JSON.stringify(results);

  return null;
}

OTP Configuration

There are two functions to implement for the OTP handling - a start and a finish step.

To set the OTP handler, implement withOtpFallback(startStep: OtpStartStep | OtpStartStepFn, finishStep: OtpFinishStep | OtpFinishStepFn), OtpStartStep and OtpFinishStep. The JavaScript snippet has a simplified example while the TypeScript snippet explains various situations. Ensure you return an object with the field phoneNumber to the resolve() function.

Retry functionality is unavailable using OTP.

function otpStart(phoneNumberNeeded, phoneValidationError) {
  return new Promise((resolve, reject) => {
    if (phoneNumberNeeded) {
      var val = prompt("Enter phone number:");
      let input = {
        phoneNumber: val,
      };
      resolve(input);
    } else {
      resolve(null);
    }
  });
}

Call the resolve(input: OtpStartInput) method to return the collected phone number to the SDK.

If you passed the phone number in the Start() call, call resolve(null) to communicate to the SDK you have the customer’s agreement to deliver the SMS OTP message. Ensure you return an object to resolve() function.

Call the reject("some error message") method to communicate to the SDK any issues while trying to obtain the phone number. Report an error if the customer cancels the SMS OTP transaction or presses the back button to leave the SMS OTP start step screen.

function otpFinish(err) {
  return new Promise((resolve, reject) => {
    if (err) {
      console.log(err);
    } else {
      var val = prompt(`Enter your OTP:`);

      let result = {
        input: {
          otp: val,
        },
        resultType: 0,
      };

      resolve(result);
    }
  });
}

Call the resolve(result: OtpFinishResult) method to return the collected OTP value in which result variable has OnSuccess value for OtpFinishResultType and the OTP value wrapped in OtpFinishInput.

Call the reject("some error message") method to communicate to the SDK any issues while trying to obtain the OTP value. Report an error if the customer cancels the SMS OTP transaction or presses the back button to exit out of the SMS OTP finish step screen.

Also call the resolve(result: OtpFinishResult) method to request a SMS OTP message in which the result variable has OnResendOtp as value for OtpFinishResultType. The SDK initiates a OtpStartStep.execute() call to allow the mobile app to restart the phone number collection logic. You can send up to three OTPs during the same authentication session.

There is one function to configure for Instant Link.

To set the Instant Link handler, withInstantLinkFallback(startStep: InstantLinkStartStep | InstantLinkStartStepFn) requires implementing the InstantLinkStartStep interface. The JavaScript snippet has a simplified example while the TypeScript snippet explains various situations. Ensure you return an object with the field phoneNumber to the resolve() function.

function instantLink(phoneNumberNeeded, phoneValidationError) {
  return new Promise((resolve, reject) => {
    if (phoneNumberNeeded) {
      var val = prompt("Enter phone number:");
      let input = {
        phoneNumber: val,
      };
      resolve(input);
    } else {
      resolve(null);
    }
  });
}

Call the resolve(input: InstantStartInput) method to return the collected phone number to the SDK.

If you passed the phone number in the Unify() call, call resolve(null) to communicate to the SDK you have the customer’s agreement to deliver the SMS OTP message. Ensure you return an object to resolve() function.

Call the reject("some error message") method to communicate to the SDK any issues while trying to obtain the phone number. Report an error if the customer cancels the Instant Link transaction or presses the back button to leave the Instant Link start step dialog.