steemit / faucet

Steemit Account Creation Web Application
MIT License
23 stars 43 forks source link

User Reported Issue - Phone number entry is removing initial "0" for Australian number #234

Closed TimCliff closed 6 years ago

TimCliff commented 6 years ago

A user has a phone number in the format +61(043)XXX-XXXX

When they enter it, it accepts it as a valid phone number: image

When it sends the validation though, it doesn't include the "0" in the "043": image

This is causing the SMS to fail to be delivered.

goldibex commented 6 years ago
gl2748 commented 6 years ago

Twilio uses E.164 formatting. In this case, the number input by the user is converted to E.164 format, which makes it appear to be incorrect.

For example: a national phone (GB in this case) that has a leading 0 number 07740 125622 is converted to +447740125622.

To the average user seeing a number sent to this E.164 number might appear to be incorrect.

Using Twilio's phone number validator however reveals it to be correct: https://www.twilio.com/lookup:

{
    "country_code": "GB",
    "phone_number": "+447740125622",
    "national_format": "07740 125622",
    "url": "https://lookups.twilio.com/v1/PhoneNumber/+447740125622",
}

The next step is to consider how we are converting user numbers:

In our case the input is a mixture of the country code and the number in the national format. this is then passed to an instance of google's libphonenumber

It is here that we might have an issue INTERNATIONAL is passed as the Phone Number Format (should be E164 as this is Twilio's preferred format), this would remove the necessity of this RegExp that removes spaces from the phone number... themselves required by the INTERNATIONAL formatter and not by E164

If this was done, we would be doing no other re-formatting of the phone number, leaving that entirely up to Google's library. At this point we would be reasonably confident that any issue with phone number formatting was not on us...

Finally we could add one more step to protect against further issues. In the examples provided by google there is a check available isValidNumber() that the user input number ought to pass before it is passed to the formatter.

Altogether this would look like:

let phoneNumber = phoneUtil.parse(req.body.phoneNumber, countryCode)
const isValid = phoneUtil.isValidNumber(phoneNumber)
  if (!isValid) {
    throw new ApiError({ field: 'phoneNumber', type: 'error_phone_invalid' });
  }
  try {
    phoneNumber = phoneUtil.format(
      phoneNumber,
      PNF.E164,
    );
  } catch (cause) {
    throw new ApiError({ cause, field: 'phoneNumber', type: 'error_phone_format' });
  }
gl2748 commented 6 years ago

closed by pr:https://github.com/steemit/faucet/pull/252