.. _phone_number_verifier: Phone Number Verifier ===================== .. contents:: :local: :depth: 3 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 :ref:`external-provisioning`, 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 :ref:`global-params` can be used. There is also one specific parameter defined for this web service: .. _phoneNumber: ``phoneNumber`` ~~~~~~~~~~~~~~~ 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`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Contains the URL, including URL scheme, of the web service, possibly also with query string. Example (with query-string): .. code-block:: none https://example.com/verify_number/?number=%phoneNumber%&appid=%appid%&version=%version% Example (without query-string, for POST): .. code-block:: xml https://example.com/verify_number/ ``Phone number verifier post data`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If filled in, the app will use POST request verify phone number. Example ( for application/x-www-form-urlencoded): .. code-block:: none number=%phoneNumber%&appid=%appid%&version=%version% Example ( for application/json ): .. code-block:: json { "number" : "%phoneNumber%", "appId": "%appid%" } ``Phone number verifier content type`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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: .. code-block:: 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: .. code-block:: 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: .. code-block:: 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: .. code-block:: 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" : "d3a4613885ea53d5f230a42c91087f25fc3de87b" } .. 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 ``d3a4613885ea53d5f230a42c91087f25fc3de87b`` will be passed to server. The ``extProvPostData`` might look like this: ``u=%username%&p=%password%&t=%authToken%``. POST method, JSON ~~~~~~~~~~~~~~~~~ request: .. code-block:: 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: .. code-block:: 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." }