﻿<a id="phone_number_verifier"></a>

# Phone Number Verifier

## Overview

Cloud Softphone uses this web service to verify the phone number of user in case phone number sign-in is enabled. With
phone number sign-in option, the app will show a registration wizard when it's started after a fresh installation.

The first step of the wizard contains an input field where the user has to fill in his phone number. When
submitted, the entered value is passed to this web service, which is expected to generate a secret PIN code and send it
to this phone number via SMS.

The user must fill in the received PIN code into a field in the second wizard page. When submitted, the app will
continue the provisioning process by invoking [external provisioning](external_provisioning.md), passing the entered phone number
as `cloud_username` and PIN code as `cloud_password`.

!!! note
    Note that this wizard will be shown to both existing users and new users. It's up to the external provisioning web
    service to check whether an account for the given phone number already exists and the web service can return existing
    credentials, or whether a new account should be created.

## Parameters

Since this web service is invoked before any accounts exist, only [global parameters](../reporting/intro.md#global-params) can be used. There is also one
specific parameter defined for this web service:

<a id="phoneNumber"></a>

### `phoneNumber` { .reference-entry }

The phone number entered by the user on the first wizard page. The number will be in international format, including
country code, without any formatting. The number will always start with `+` sign.

Example: `+15551231234` , `+420800123456`

## Configuration

The web service is configured via Cloud Softphone web portal, in white-label configuration step. This option becomes
available when phone number sign-in is enabled in Features step.

### `Phone number verifier url` { .reference-entry }

Contains the URL, including URL scheme, of the web service, possibly also with query string.

Example (with query-string):

```
https://example.com/verify_number/?number=%phoneNumber%&appid=%appid%&version=%version%
```

Example (without query-string, for POST):

```xml
https://example.com/verify_number/
```

### `Phone number verifier post data` { .reference-entry }

If filled in, the app will use POST request verify phone number.

Example (for application/x-www-form-urlencoded):

```
number=%phoneNumber%&appid=%appid%&version=%version%
```

Example (for application/json):

```json
{ "number" : "%phoneNumber%", "appId": "%appid%" }
```

### `Phone number verifier content type` { .reference-entry }

Specifies the value of Content-Type header to be sent in the request. If not specified, the app will default to
`application/x-www-form-urlencoded`

## Response

The response will be considered successful if the response code is `2xx OK` and the body is valid (or if there is
no body). In this case, the app will switch to the second wizard page and the user can wait for the SMS to arrive.

In case of error, the response code should be non-2xx. The app will try to parse the body and extract "message"
value from it. This message is then shown to the user in a message box. In case parsing fails, or no message is
found, the app shows the first 100 characters of the raw response body.

In case the response code is `2xx OK` and the body is not empty, it is parsed according to Content-Type and
treated as a key->value map, where both keys and values are strings. The keys can be referenced in the extProv web
service used in 2nd wizard step as `%key%` placeholders and the app will replace them with the corresponding
values.

This can be used to further secure the registration wizard by generating a unique auth token together with the PIN
code. The PIN code is sent via SMS, the token is stored on server and sent in the response back to the client.
When the user fills in the PIN code from SMS in second wizard step, the client will send both the token and PIN code
and the server can validate them. This makes "guessing" the right PIN code impossible without also knowing the token,
which is transferred between the client and server over an encrypted connection.

## Examples

### GET method (empty response)

request:

```http
GET /verify/?phone=%2B15551231234&appid=com.cloudsoftphone.app HTTP/1.1
Host: example.com
Connection: close
Cache-Control: max-age=0
User-Agent: CloudSoftphone/1.5.6
```

response:

```http
HTTP/1.1 200 OK
Date: Sun, 15 Mar 2015 00:46:17 GMT
Server: Apache/2.4.7 (Ubuntu)
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
```

### GET method (response with token)

request:

```http
GET /verify/?phone=%2B15551231234&appid=com.cloudsoftphone.app HTTP/1.1
Host: example.com
Connection: close
Cache-Control: max-age=0
User-Agent: CloudSoftphone/1.5.6
```

response:

```http
HTTP/1.1 200 OK
Date: Sun, 15 Mar 2015 00:46:17 GMT
Server: Apache/2.4.7 (Ubuntu)
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 123
Content-Type: application/json
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive

{
    "authToken" : "<token-from-register-phone-response>"
}
```

!!! note
    In case the app uses `%authToken%` in external provisioning web service definition, which is used to complete
    the second step of registration wizard, the value returned in `authToken` from the previous step will be passed to
    server. The `extProvPostData` might look like this: `u=%username%&p=%password%&t=%authToken%`.

### POST method, JSON

request:

```http
POST /verify/ HTTP/1.1
Host: example.com
Connection: close
Cache-Control: max-age=0
User-Agent: CloudSoftphone/1.5.6
Content-Type: application/json
Content-Length: 183

{
    "phone"    : "+155",
    "appid"    : "com.cloudsoftphone.app"
}
```

response:

```http
HTTP/1.1 400 Bad Bad
Date: Sun, 15 Mar 2015 00:46:17 GMT
Server: Apache/2.4.7 (Ubuntu)
Vary: Accept-Encoding
Content-Type: application/json
Content-Length: 123
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive

{
    "message"  :  "The number +155 is invalid."
}
```