User interaction framework for delivery

The /userInteraction framework for delivery allows the Service Provider to:

  1. Request additional information from the user once the service delivery process has started with fields.

  2. Push an action to be performed by the users device with action.

For a complete look at the architecture and the order of operations have a look at our Architecture pages.

/userInteraction is an API operation like any other of the ones listed in the developer portal API page, for example /ccm/install. The difference is that instead of interacting with the card, the SP gets to interact with the user.

The general flow of service delivery with /userInteraction and field (the flow is the same for action):

Terms and abbreviations

Dictionary - A map of strings the key represents language ID and the value is the translated text. en should be used as fallback and is mandatory to be supplied.

API

As described in the API documentation under the title Service Delivery requests, as soon as the Service Provider receives the service delivery request from the client, it will be able to request specific data from the user or make the client do an action, in other words, do a user interaction. To do that, the Service Provider just needs to POST a JSON formatted request to the /userInteraction endpoint that is either a field or action.

Field

The information that is requested from the user is presented in a form to which many fields can be added. Each field defined in the request has a direct correspondence with a system UI component that will be rendered in the form shown to the user. For a better user experience grouping of related fields is a good idea although generally the forms should be kept as short as possible. Once a user is done with a form they submit it with the submit button. This means that if a field depends on input from another field they need to be in separate forms.

If the Service Providers service requires some information from the user before starting service delivery, we recommend to use the Service Description mechanism rather than field, as it has been designed to be used in the setup phase.

A user interaction request is composed by an array fields. Each element of fields is described in the following table:

Fields inside a request
Name Description Type
label The text label that will appear together with the system UI component defined by the type field. Multilanguage is supported. Dictionary
id The id used to identify this field String
type The type of UI control that the user will see in the Fidesmo App String
format Provides an extra information about how the UI control will be rendered or what kind of data it will support. The format is optional and if not supplied or an unknown format is used the field falls back to the default. String

And finally, this is the list of type and format supported:

Supported data type and format
Name Type Format Description Label Returns
Date field date - Shows a date input to the user The text that should be shown above the date input supplied as a Dictionary. A date as a string formatted as YYYY-MM-DD.
Input text field edit text Shows a text input. Default if format is not specified or not supported. The label that should be shown above the text input supplied as a Dictionary. The user input as a string or an empty string if nothing has been entered.
number Text input, accepting numbers only The label that should be shown above the number input supplied as a Dictionary. The numeric user input as a string or an empty string if nothing has been entered.
obfuscated-number Numeric input for sensitive data. Should only accept numbers and obfuscate them by default unless the user toggles them to be shown. Should not use system keyboard, dictionaries or auto-correct features. The label that should be shown above the number input supplied as a Dictionary. The user input as a string or an empty string if nothing has been entered.
password Text input for entering a password. Should not use dictionaries or auto-correct features. May be obfuscated. Platform specific best practices for entering password data into a UI component are expected to be followed. The label that should be shown above the password input supplied as a Dictionary. The user input as a string or an empty string if nothing has been entered.
email Text input for entering an email. The label that should be shown above the email input supplied as a Dictionary. The user input as a string or an empty string if nothing has been entered.
Markdown text field text - Shows a static text to the user. The text that should be shown, supplied as a Dictionary. The text may contain basic markdown elements like bold, emphasis or links. -
Check box field checkbox - Shows a checkbox with text to the user The label that should be shown with the checkbox supplied as a Dictionary. Either the string "true" or "false".
Option field option button A button or a set of buttons. If a button is pressed by the user the form is submitted. Having buttons in the form automatically hides the submit-button. Default if format is not specified or not supported. The labels, divided by \n, to be shown on the buttons supplied as a Dictionary. The numeric, zero-based position of the picked button in the provided array as a string.
radio Set of radio buttons for each line of a label. Dictionary where the key represents language ID and the value is the labels, divided by \n, to be shown next to the radiobuttons. The numeric, zero-based position of the picked radiobutton in the provided array as a string.
Payment card field paymentcard - The label shown next to the input field supplied as a Dictionary. Payment card information as number, expiration date and CVV code A PAN validated with the Luhn algorithm. The "cvv" field might be optional depending on Service Provider Configuration, then it can be left empty. JSONObject: { "cardNumber": "XXXXXXXXXXXXXXXX", "expiryMonth": Int, "expiryYear", Int, "cvv", "XXX" }

Data validation

The application that the user is using is expected to validate the context to at least match the expected return format and size as per the above table.

API

The Service Provider should POST a JSON formatted request to the /userInteraction endpoint similar to the following structure:

{
          "fields": [{
            "label": {
              "en": "English label",
              "se": "Swedish label"
            },
            "id": "any_field_id",
            "type": "edit",
            "format": "number"
            ...
          }],
          "encrypted": "false"
        }

Result

The userInteraction request will yield an operationId and UUID. After some time (the user is filling in the required information) the Service Provider will receive the ID of the operation, a status code and the results. The result will be in JSON and formatted like for example:

{
          "operationId": "0276F6A6-E21C-4307-B63C-1F70D6C36045",
          "sessionId": "C4D14B40-8F1C-456C-A7E2-4069B5F8CBBC",
          "statusCode": 200,
          "fields": {
            "any_field_id": "field_string_value"
          }
        }

Encryption

It is possible to specify that the data submitted by the user travels encrypted from the mobile client to the Service Provider, so that sensitive data such as payment card details cannot be compromised.

Encrypted user interactions are done with a combination of symmetric and asymmetric encryption. An ephemeral AES key is generated by the client and used to encrypt the /userInteraction data. Then, this key is encrypted with the public key of the Service Provider. The client returns the ephemeral-key encrypted data, and the public-key encrypted ephemeral key. Upon receival, the Service Provider decrypts the ephemeral key with its private key, and then, with the newly decrypted ephemeral key, decrypts all the data.

To activate encryption the Service Provider needs to pass a public key as a certificate along with the service description:

{
          "title": "The encrypted userInteraction service",
          "description": "This is an encrypted userInteraction service.
          Keep out of reach from children.",
          ...
          "certificate": [A X.509 certificate encoded as ASN1.DER]
        }

To encrypt a /userInteraction the Service Provider must also set the encrypted flag to true like for example:

{
          "fields": [{
            "label": {
              "en": "English label"
            },
            "id": "any_field_id",
            "type": "edit",
            "format": "number",
            ...
          }],
          "encrypted": "true"
        }

The encrypted data together with the encrypted ephemeral key will be sent back as previously described in the Result section but with the fields being encrypted and the additional field "ephemeralKey":

{
          "operationId" : "0276F6A6-E21C-4307-B63C-1F70D6C36045",
          "sessionId" : "C4D14B40-8F1C-456C-A7E2-4069B5F8CBBC",
          "statusCode": 200,
          "fields": {
            "any_field_id": [byte array in a hex form]
          },
          "ephemeralKey": [byte array in a hex form]
        }

The "ephemeralKey" is encrypted using RSA/OAEP algorithm with a SHA512 for hashing and MGF1 Padding (RSA/NONE/OAEPWithSHA512AndMGF1Padding). To obtain field data one needs to decrypt the "ephemeralKey" first and then using the obtained key to decrypt each field separately using AES/CBC algorithm with a PKCS7 padding (AES/CBC/PKCS7Padding). As initialization vector an array with 16 zero bytes can be used.

Example

Show the user a policy text plus a checkbox for accepting the very same.

{
            "fields": [
              {
                "label": {
                  "en": "Generic Brands collects information to provide a
                  better service our users. The information we collect might
                  include your name, telephone number and credit card."
                },
                "id": "my_text_field_id",
                "type": "edit",
                "format": "text"
              },
              {
                "label": {
                  "en": "I accept terms and conditions"
                },
                "id": "my_text_checkbox_id",
                "type": "checkbox"
              }
            ],
            "encrypted" : "false"
          }

Returned when user checks box and presses submit

{
          "operationId" : "MOCK",
          "sessionId" : "MOCK",
          "statusCode": 200,
          "fields": {
            "my_text_field_id": "",
            "my_text_checkbox_id": "true"
          }
        }

Action

By sending list of action to the client the Service Provider can make the client perform a sequence of actions or a single action, for example make a call. The structure of the action object is described in the following table:

action
Name Type Description
description Translations The description/label that might appear in the UI if it is deemed necessary by the client. Supplied as a Dictionary.
name String The id used to identify this field.
parameters Map Any parameters that are necessary for the completion of the action.

When the client receives an action it will complete it to the best of it's ability, however, sometimes the client is unable to complete the action. For example a UI client running on the users phone will have no problem calling a phonenumber, however, a tablet UI client might not be able to do the same if it doesn't have a SIM. In this case the tablet UI client will instead show the user the description text as well as any passed parameters, so that the user can compete the action on another device.

Names

There is only a single action right now, called phonecall. It has a single parameter called number which contains the phonenumber that the UI client should call.

phonenumber action JSONObject with number parameter set to +46XXXXXXXXX:

          {
            "description": { /* ... */ },
            "name": "phonenumber",
            "parameters": {
              "number": "+46XXXXXXXXX"
            }
          }
        

API

The Service Provider should POST a JSON formatted request to the /userInteraction endpoint similar to the following structure:

{
          "actions": [{
            "description": {
              "en": "English description",
              "se": "Swedish description"
            },
            "name": "any_action_name",
            "parameters": {
              "parameter_name": "parameter_value",
              "parameter_name": "parameter_value"
            }
          }],
          "encrypted": "false"
        }

Example

{
          "actions": [{
            "description": {
              "en": "Call this number +46XXXXXXXXX"
            },
            "name": "phonecall",
            "parameters": {
              "number": "+46XXXXXXXXX"
            }
          }]
        }

On the client side this is what is received:

          {
            "operationType": "action",
            "operationId": [omitted],
            "encrypted": false,
            "completed": false,
            "actions": [{
              "description": "Call this number +46XXXXXXXXX",
              "name": "phonecall",
              "parameters": {
                "number": "+46XXXXXXXXX"
              }
            }]
          }
        

The result would be that the UI client calls the number +46XXXXXXXXX.