mirror of
https://github.com/moparisthebest/mail
synced 2024-12-21 23:08:50 -05:00
Add phone number validation in wmail signup
This commit is contained in:
parent
fb0454142c
commit
9d420f3cdc
@ -45,7 +45,8 @@
|
||||
"forge",
|
||||
"Lawnchair",
|
||||
"_",
|
||||
"openpgp"
|
||||
"openpgp",
|
||||
"PhoneNumber"
|
||||
],
|
||||
|
||||
"globals": {}
|
||||
|
@ -264,6 +264,9 @@ module.exports = function(grunt) {
|
||||
'src/lib/lawnchair/lawnchair-git.js',
|
||||
'src/lib/lawnchair/lawnchair-adapter-webkit-sqlite-git.js',
|
||||
'src/lib/lawnchair/lawnchair-adapter-indexed-db-git.js',
|
||||
'src/lib/phonenumber/PhoneNumberMetadata.js',
|
||||
'src/lib/phonenumber/PhoneNumberNormalizer.js',
|
||||
'src/lib/phonenumber/PhoneNumber.js',
|
||||
'dist/js/app.browserified.js',
|
||||
'<%= ngtemplates.mail.dest %>'
|
||||
],
|
||||
@ -301,6 +304,9 @@ module.exports = function(grunt) {
|
||||
'src/lib/lawnchair/lawnchair-git.js',
|
||||
'src/lib/lawnchair/lawnchair-adapter-webkit-sqlite-git.js',
|
||||
'src/lib/lawnchair/lawnchair-adapter-indexed-db-git.js',
|
||||
'src/lib/phonenumber/PhoneNumberMetadata.js',
|
||||
'src/lib/phonenumber/PhoneNumberNormalizer.js',
|
||||
'src/lib/phonenumber/PhoneNumber.js',
|
||||
'test/unit/index.browserified.js'
|
||||
],
|
||||
dest: 'test/unit/index.js',
|
||||
|
@ -3,20 +3,28 @@
|
||||
var CreateAccountCtrl = function($scope, $location, $routeParams, $q, auth, admin, appConfig) {
|
||||
!$routeParams.dev && !auth.isInitialized() && $location.path('/'); // init app
|
||||
|
||||
// init phone region
|
||||
$scope.region = 'DE';
|
||||
|
||||
$scope.createWhiteoutAccount = function() {
|
||||
if ($scope.form.$invalid) {
|
||||
$scope.errMsg = 'Please fill out all required fields!';
|
||||
return;
|
||||
}
|
||||
|
||||
var emailAddress = $scope.user + '@' + appConfig.config.wmailDomain;
|
||||
|
||||
return $q(function(resolve) {
|
||||
$scope.busy = true;
|
||||
$scope.errMsg = undefined; // reset error msg
|
||||
resolve();
|
||||
|
||||
}).then(function() {
|
||||
// read form values
|
||||
var emailAddress = $scope.user + '@' + appConfig.config.wmailDomain;
|
||||
var phone = PhoneNumber.Parse($scope.dial, $scope.region);
|
||||
if (!phone || !phone.internationalNumber) {
|
||||
throw new Error('Invalid phone number!');
|
||||
}
|
||||
|
||||
// set to state for next view
|
||||
auth.setCredentials({
|
||||
emailAddress: emailAddress,
|
||||
@ -28,7 +36,7 @@ var CreateAccountCtrl = function($scope, $location, $routeParams, $q, auth, admi
|
||||
return admin.createUser({
|
||||
emailAddress: emailAddress,
|
||||
password: $scope.pass,
|
||||
phone: $scope.phone.replace(/\s+/g, ''), // remove spaces from the phone number
|
||||
phone: phone.internationalNumber,
|
||||
betaCode: $scope.betaCode.toUpperCase()
|
||||
});
|
||||
|
||||
|
340
src/lib/phonenumber/PhoneNumber.js
Normal file
340
src/lib/phonenumber/PhoneNumber.js
Normal file
@ -0,0 +1,340 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
var PhoneNumber = (function (dataBase) {
|
||||
// Use strict in our context only - users might not want it
|
||||
'use strict';
|
||||
|
||||
var MAX_PHONE_NUMBER_LENGTH = 50,
|
||||
NON_ALPHA_CHARS = /[^a-zA-Z]/g,
|
||||
NON_DIALABLE_CHARS = /[^,#+\*\d]/g,
|
||||
NON_DIALABLE_CHARS_ONCE = new RegExp(NON_DIALABLE_CHARS.source),
|
||||
BACKSLASH = /\\/g,
|
||||
SPLIT_FIRST_GROUP = /^(\d+)(.*)$/,
|
||||
LEADING_PLUS_CHARS_PATTERN = /^[+\uFF0B]+/g,
|
||||
|
||||
// Format of the string encoded meta data. If the name contains "^" or "$"
|
||||
// we will generate a regular expression from the value, with those special
|
||||
// characters as prefix/suffix.
|
||||
META_DATA_ENCODING = ["region",
|
||||
"^(?:internationalPrefix)",
|
||||
"nationalPrefix",
|
||||
"^(?:nationalPrefixForParsing)",
|
||||
"nationalPrefixTransformRule",
|
||||
"nationalPrefixFormattingRule",
|
||||
"^possiblePattern$",
|
||||
"^nationalPattern$",
|
||||
"formats"],
|
||||
|
||||
FORMAT_ENCODING = ["^pattern$",
|
||||
"nationalFormat",
|
||||
"^leadingDigits",
|
||||
"nationalPrefixFormattingRule",
|
||||
"internationalFormat"],
|
||||
|
||||
regionCache = {};
|
||||
|
||||
// Parse an array of strings into a convenient object. We store meta
|
||||
// data as arrays since thats much more compact than JSON.
|
||||
function ParseArray(array, encoding, obj) {
|
||||
for (var n = 0; n < encoding.length; ++n) {
|
||||
var value = array[n];
|
||||
if (!value)
|
||||
continue;
|
||||
var field = encoding[n];
|
||||
var fieldAlpha = field.replace(NON_ALPHA_CHARS, "");
|
||||
if (field != fieldAlpha)
|
||||
value = new RegExp(field.replace(fieldAlpha, value));
|
||||
obj[fieldAlpha] = value;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Parse string encoded meta data into a convenient object
|
||||
// representation.
|
||||
function ParseMetaData(countryCode, md) {
|
||||
var array = JSON.parse(md);
|
||||
md = ParseArray(array,
|
||||
META_DATA_ENCODING,
|
||||
{ countryCode: countryCode });
|
||||
regionCache[md.region] = md;
|
||||
return md;
|
||||
}
|
||||
|
||||
// Parse string encoded format data into a convenient object
|
||||
// representation.
|
||||
function ParseFormat(md) {
|
||||
var formats = md.formats;
|
||||
if (!formats) {
|
||||
return null;
|
||||
}
|
||||
// Bail if we already parsed the format definitions.
|
||||
if (Object.prototype.toString.call(formats[0]) != "[object Array]")
|
||||
return;
|
||||
for (var n = 0; n < formats.length; ++n) {
|
||||
formats[n] = ParseArray(formats[n],
|
||||
FORMAT_ENCODING,
|
||||
{});
|
||||
}
|
||||
}
|
||||
|
||||
// Search for the meta data associated with a region identifier ("US") in
|
||||
// our database, which is indexed by country code ("1"). Since we have
|
||||
// to walk the entire database for this, we cache the result of the lookup
|
||||
// for future reference.
|
||||
function FindMetaDataForRegion(region) {
|
||||
// Check in the region cache first. This will find all entries we have
|
||||
// already resolved (parsed from a string encoding).
|
||||
var md = regionCache[region];
|
||||
if (md)
|
||||
return md;
|
||||
for (var countryCode in dataBase) {
|
||||
var entry = dataBase[countryCode];
|
||||
// Each entry is a string encoded object of the form '["US..', or
|
||||
// an array of strings. We don't want to parse the string here
|
||||
// to save memory, so we just substring the region identifier
|
||||
// and compare it. For arrays, we compare against all region
|
||||
// identifiers with that country code. We skip entries that are
|
||||
// of type object, because they were already resolved (parsed into
|
||||
// an object), and their country code should have been in the cache.
|
||||
if (Object.prototype.toString.call(entry) == "[object Array]") {
|
||||
for (var n = 0; n < entry.length; n++) {
|
||||
if (typeof entry[n] == "string" && entry[n].substr(2,2) == region) {
|
||||
if (n > 0) {
|
||||
// Only the first entry has the formats field set.
|
||||
// Parse the main country if we haven't already and use
|
||||
// the formats field from the main country.
|
||||
if (typeof entry[0] == "string")
|
||||
entry[0] = ParseMetaData(countryCode, entry[0]);
|
||||
var formats = entry[0].formats;
|
||||
var current = ParseMetaData(countryCode, entry[n]);
|
||||
current.formats = formats;
|
||||
return entry[n] = current;
|
||||
}
|
||||
|
||||
entry[n] = ParseMetaData(countryCode, entry[n]);
|
||||
return entry[n];
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (typeof entry == "string" && entry.substr(2,2) == region)
|
||||
return dataBase[countryCode] = ParseMetaData(countryCode, entry);
|
||||
}
|
||||
}
|
||||
|
||||
// Format a national number for a given region. The boolean flag "intl"
|
||||
// indicates whether we want the national or international format.
|
||||
function FormatNumber(regionMetaData, number, intl) {
|
||||
// We lazily parse the format description in the meta data for the region,
|
||||
// so make sure to parse it now if we haven't already done so.
|
||||
ParseFormat(regionMetaData);
|
||||
var formats = regionMetaData.formats;
|
||||
if (!formats) {
|
||||
return null;
|
||||
}
|
||||
for (var n = 0; n < formats.length; ++n) {
|
||||
var format = formats[n];
|
||||
// The leading digits field is optional. If we don't have it, just
|
||||
// use the matching pattern to qualify numbers.
|
||||
if (format.leadingDigits && !format.leadingDigits.test(number))
|
||||
continue;
|
||||
if (!format.pattern.test(number))
|
||||
continue;
|
||||
if (intl) {
|
||||
// If there is no international format, just fall back to the national
|
||||
// format.
|
||||
var internationalFormat = format.internationalFormat;
|
||||
if (!internationalFormat)
|
||||
internationalFormat = format.nationalFormat;
|
||||
// Some regions have numbers that can't be dialed from outside the
|
||||
// country, indicated by "NA" for the international format of that
|
||||
// number format pattern.
|
||||
if (internationalFormat == "NA")
|
||||
return null;
|
||||
// Prepend "+" and the country code.
|
||||
number = "+" + regionMetaData.countryCode + " " +
|
||||
number.replace(format.pattern, internationalFormat);
|
||||
} else {
|
||||
number = number.replace(format.pattern, format.nationalFormat);
|
||||
// The region has a national prefix formatting rule, and it can be overwritten
|
||||
// by each actual number format rule.
|
||||
var nationalPrefixFormattingRule = regionMetaData.nationalPrefixFormattingRule;
|
||||
if (format.nationalPrefixFormattingRule)
|
||||
nationalPrefixFormattingRule = format.nationalPrefixFormattingRule;
|
||||
if (nationalPrefixFormattingRule) {
|
||||
// The prefix formatting rule contains two magic markers, "$NP" and "$FG".
|
||||
// "$NP" will be replaced by the national prefix, and "$FG" with the
|
||||
// first group of numbers.
|
||||
var match = number.match(SPLIT_FIRST_GROUP);
|
||||
if (match) {
|
||||
var firstGroup = match[1];
|
||||
var rest = match[2];
|
||||
var prefix = nationalPrefixFormattingRule;
|
||||
prefix = prefix.replace("$NP", regionMetaData.nationalPrefix);
|
||||
prefix = prefix.replace("$FG", firstGroup);
|
||||
number = prefix + rest;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (number == "NA") ? null : number;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function NationalNumber(regionMetaData, number) {
|
||||
this.region = regionMetaData.region;
|
||||
this.regionMetaData = regionMetaData;
|
||||
this.nationalNumber = number;
|
||||
this.internationalFormat = FormatNumber(this.regionMetaData, this.nationalNumber, true);
|
||||
this.nationalFormat = FormatNumber(this.regionMetaData, this.nationalNumber, false);
|
||||
this.internationalNumber = this.internationalFormat ? this.internationalFormat.replace(NON_DIALABLE_CHARS, "") : null;
|
||||
};
|
||||
|
||||
// Check whether the number is valid for the given region.
|
||||
function IsValidNumber(number, md) {
|
||||
return md.possiblePattern.test(number);
|
||||
}
|
||||
|
||||
// Check whether the number is a valid national number for the given region.
|
||||
function IsNationalNumber(number, md) {
|
||||
return IsValidNumber(number, md) && md.nationalPattern.test(number);
|
||||
}
|
||||
|
||||
// Determine the country code a number starts with, or return null if
|
||||
// its not a valid country code.
|
||||
function ParseCountryCode(number) {
|
||||
for (var n = 1; n <= 3; ++n) {
|
||||
var cc = number.substr(0,n);
|
||||
if (dataBase[cc])
|
||||
return cc;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Parse an international number that starts with the country code. Return
|
||||
// null if the number is not a valid international number.
|
||||
function ParseInternationalNumber(number) {
|
||||
var ret;
|
||||
|
||||
// Parse and strip the country code.
|
||||
var countryCode = ParseCountryCode(number);
|
||||
if (!countryCode)
|
||||
return null;
|
||||
number = number.substr(countryCode.length);
|
||||
|
||||
// Lookup the meta data for the region (or regions) and if the rest of
|
||||
// the number parses for that region, return the parsed number.
|
||||
var entry = dataBase[countryCode];
|
||||
if (Object.prototype.toString.call(entry) == "[object Array]") {
|
||||
for (var n = 0; n < entry.length; ++n) {
|
||||
if (typeof entry[n] == "string")
|
||||
entry[n] = ParseMetaData(countryCode, entry[n]);
|
||||
if (n > 0)
|
||||
entry[n].formats = entry[0].formats;
|
||||
ret = ParseNationalNumber(number, entry[n]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (typeof entry == "string")
|
||||
entry = dataBase[countryCode] = ParseMetaData(countryCode, entry);
|
||||
return ParseNationalNumber(number, entry);
|
||||
}
|
||||
|
||||
// Parse a national number for a specific region. Return null if the
|
||||
// number is not a valid national number (it might still be a possible
|
||||
// number for parts of that region).
|
||||
function ParseNationalNumber(number, md) {
|
||||
if (!md.possiblePattern.test(number) ||
|
||||
!md.nationalPattern.test(number)) {
|
||||
return null;
|
||||
}
|
||||
// Success.
|
||||
return new NationalNumber(md, number);
|
||||
}
|
||||
|
||||
// Parse a number and transform it into the national format, removing any
|
||||
// international dial prefixes and country codes.
|
||||
function ParseNumber(number, defaultRegion) {
|
||||
var ret;
|
||||
|
||||
// Remove formating characters and whitespace.
|
||||
number = PhoneNumberNormalizer.Normalize(number);
|
||||
|
||||
// If there is no defaultRegion, we can't parse international access codes.
|
||||
if (!defaultRegion && number.charAt(0) !== '+')
|
||||
return null;
|
||||
|
||||
// Detect and strip leading '+'.
|
||||
if (number.charAt(0) === '+')
|
||||
return ParseInternationalNumber(number.replace(LEADING_PLUS_CHARS_PATTERN, ""));
|
||||
|
||||
// Lookup the meta data for the given region.
|
||||
var md = FindMetaDataForRegion(defaultRegion.toUpperCase());
|
||||
|
||||
// See if the number starts with an international prefix, and if the
|
||||
// number resulting from stripping the code is valid, then remove the
|
||||
// prefix and flag the number as international.
|
||||
if (md.internationalPrefix.test(number)) {
|
||||
var possibleNumber = number.replace(md.internationalPrefix, "");
|
||||
ret = ParseInternationalNumber(possibleNumber);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
// This is not an international number. See if its a national one for
|
||||
// the current region. National numbers can start with the national
|
||||
// prefix, or without.
|
||||
if (md.nationalPrefixForParsing) {
|
||||
// Some regions have specific national prefix parse rules. Apply those.
|
||||
var withoutPrefix = number.replace(md.nationalPrefixForParsing,
|
||||
md.nationalPrefixTransformRule || '');
|
||||
ret = ParseNationalNumber(withoutPrefix, md);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
// If there is no specific national prefix rule, just strip off the
|
||||
// national prefix from the beginning of the number (if there is one).
|
||||
var nationalPrefix = md.nationalPrefix;
|
||||
if (nationalPrefix && number.indexOf(nationalPrefix) == 0 &&
|
||||
(ret = ParseNationalNumber(number.substr(nationalPrefix.length), md))) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = ParseNationalNumber(number, md);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
// Now lets see if maybe its an international number after all, but
|
||||
// without '+' or the international prefix.
|
||||
ret = ParseInternationalNumber(number);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
// If the number matches the possible numbers of the current region,
|
||||
// return it as a possible number.
|
||||
if (md.possiblePattern.test(number))
|
||||
return new NationalNumber(md, number);
|
||||
|
||||
// We couldn't parse the number at all.
|
||||
return null;
|
||||
}
|
||||
|
||||
function IsPlainPhoneNumber(number) {
|
||||
if (typeof number !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
var length = number.length;
|
||||
var isTooLong = (length > MAX_PHONE_NUMBER_LENGTH);
|
||||
var isEmpty = (length === 0);
|
||||
return !(isTooLong || isEmpty || NON_DIALABLE_CHARS_ONCE.test(number));
|
||||
}
|
||||
|
||||
return {
|
||||
IsPlain: IsPlainPhoneNumber,
|
||||
Parse: ParseNumber
|
||||
};
|
||||
})(PHONE_NUMBER_META_DATA);
|
2
src/lib/phonenumber/PhoneNumberMetadata.js
Normal file
2
src/lib/phonenumber/PhoneNumberMetadata.js
Normal file
File diff suppressed because one or more lines are too long
48
src/lib/phonenumber/PhoneNumberNormalizer.js
Normal file
48
src/lib/phonenumber/PhoneNumberNormalizer.js
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
var PhoneNumberNormalizer = (function() {
|
||||
"use strict";
|
||||
|
||||
var UNICODE_DIGITS = /[\uFF10-\uFF19\u0660-\u0669\u06F0-\u06F9]/g,
|
||||
VALID_ALPHA_PATTERN = /[a-zA-Z]/g,
|
||||
LEADING_PLUS_CHARS_PATTERN = /^[+\uFF0B]+/g,
|
||||
NON_DIALABLE_CHARS = /[^,#+\*\d]/g;
|
||||
|
||||
// Map letters to numbers according to the ITU E.161 standard
|
||||
var E161 = {
|
||||
'a': 2, 'b': 2, 'c': 2,
|
||||
'd': 3, 'e': 3, 'f': 3,
|
||||
'g': 4, 'h': 4, 'i': 4,
|
||||
'j': 5, 'k': 5, 'l': 5,
|
||||
'm': 6, 'n': 6, 'o': 6,
|
||||
'p': 7, 'q': 7, 'r': 7, 's': 7,
|
||||
't': 8, 'u': 8, 'v': 8,
|
||||
'w': 9, 'x': 9, 'y': 9, 'z': 9
|
||||
};
|
||||
|
||||
// Normalize a number by converting unicode numbers and symbols to their
|
||||
// ASCII equivalents and removing all non-dialable characters.
|
||||
function NormalizeNumber(number, numbersOnly) {
|
||||
if (typeof number !== 'string') {
|
||||
return '';
|
||||
}
|
||||
|
||||
number = number.replace(UNICODE_DIGITS,
|
||||
function (ch) {
|
||||
return String.fromCharCode(48 + (ch.charCodeAt(0) & 0xf));
|
||||
});
|
||||
if (!numbersOnly) {
|
||||
number = number.replace(VALID_ALPHA_PATTERN,
|
||||
function (ch) {
|
||||
return String(E161[ch.toLowerCase()] || 0);
|
||||
});
|
||||
}
|
||||
number = number.replace(LEADING_PLUS_CHARS_PATTERN, "+");
|
||||
number = number.replace(NON_DIALABLE_CHARS, "");
|
||||
return number;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
Normalize: NormalizeNumber
|
||||
};
|
||||
})();
|
@ -5,7 +5,7 @@
|
||||
</header>
|
||||
<main class="page__main">
|
||||
<h2 class="typo-title">Create Whiteout account</h2>
|
||||
<p class="typo-paragraph">Please fill out the following form. You will need a <em>beta access code</em> during the private beta period. To participate in the private beta just <a href="mailto:support@whiteout.io?subject=Beta%20Access%20Code&body=I%20would%20like%20to%20try%20the%20encrypted%20Whiteout%20Mailbox%20service.%20Please%20send%20me%20a%20beta%20access%20code." target="_blank">get in touch</a>.</p>
|
||||
<p class="typo-paragraph">Please fill out the following form. You will need a <em>beta access code</em> during the private beta period. To participate in the private beta please <a href="http://eepurl.com/ba09in" target="_blank">sign up</a>.</p>
|
||||
<form class="form" name="form">
|
||||
<p class="form__error-message" ng-show="errMsg">{{errMsg}}</p>
|
||||
<div class="form__row">
|
||||
@ -27,8 +27,265 @@
|
||||
<input class="input-text right" ng-model="confirmPass" required type="password" placeholder="Confirm password" ng-class="{'input-text--error': (pass || confirmPass) && pass !== confirmPass}" tabindex="4">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form__row">
|
||||
<input class="input-text" type="tel" ng-model="phone" required placeholder="Mobile phone number (e.g. +49 170 1234567)" tabindex="5">
|
||||
<div class="form__row form__row--multi">
|
||||
<div class="form__col" style="max-width:130px">
|
||||
<label class="input-select">
|
||||
<select ng-model="region">
|
||||
<option value="AF">Afghanistan</option>
|
||||
<option value="AX">Åland Islands</option>
|
||||
<option value="AL">Albania</option>
|
||||
<option value="DZ">Algeria</option>
|
||||
<option value="AS">American Samoa</option>
|
||||
<option value="AD">Andorra</option>
|
||||
<option value="AO">Angola</option>
|
||||
<option value="AI">Anguilla</option>
|
||||
<option value="AQ">Antarctica</option>
|
||||
<option value="AG">Antigua and Barbuda</option>
|
||||
<option value="AR">Argentina</option>
|
||||
<option value="AM">Armenia</option>
|
||||
<option value="AW">Aruba</option>
|
||||
<option value="AU">Australia</option>
|
||||
<option value="AT">Austria</option>
|
||||
<option value="AZ">Azerbaijan</option>
|
||||
<option value="BS">Bahamas</option>
|
||||
<option value="BH">Bahrain</option>
|
||||
<option value="BD">Bangladesh</option>
|
||||
<option value="BB">Barbados</option>
|
||||
<option value="BY">Belarus</option>
|
||||
<option value="BE">Belgium</option>
|
||||
<option value="BZ">Belize</option>
|
||||
<option value="BJ">Benin</option>
|
||||
<option value="BM">Bermuda</option>
|
||||
<option value="BT">Bhutan</option>
|
||||
<option value="BO">Bolivia, Plurinational State of</option>
|
||||
<option value="BQ">Bonaire, Sint Eustatius and Saba</option>
|
||||
<option value="BA">Bosnia and Herzegovina</option>
|
||||
<option value="BW">Botswana</option>
|
||||
<option value="BV">Bouvet Island</option>
|
||||
<option value="BR">Brazil</option>
|
||||
<option value="IO">British Indian Ocean Territory</option>
|
||||
<option value="BN">Brunei Darussalam</option>
|
||||
<option value="BG">Bulgaria</option>
|
||||
<option value="BF">Burkina Faso</option>
|
||||
<option value="BI">Burundi</option>
|
||||
<option value="KH">Cambodia</option>
|
||||
<option value="CM">Cameroon</option>
|
||||
<option value="CA">Canada</option>
|
||||
<option value="CV">Cape Verde</option>
|
||||
<option value="KY">Cayman Islands</option>
|
||||
<option value="CF">Central African Republic</option>
|
||||
<option value="TD">Chad</option>
|
||||
<option value="CL">Chile</option>
|
||||
<option value="CN">China</option>
|
||||
<option value="CX">Christmas Island</option>
|
||||
<option value="CC">Cocos (Keeling) Islands</option>
|
||||
<option value="CO">Colombia</option>
|
||||
<option value="KM">Comoros</option>
|
||||
<option value="CG">Congo</option>
|
||||
<option value="CD">Congo, the Democratic Republic of the</option>
|
||||
<option value="CK">Cook Islands</option>
|
||||
<option value="CR">Costa Rica</option>
|
||||
<option value="CI">Côte d'Ivoire</option>
|
||||
<option value="HR">Croatia</option>
|
||||
<option value="CU">Cuba</option>
|
||||
<option value="CW">Curaçao</option>
|
||||
<option value="CY">Cyprus</option>
|
||||
<option value="CZ">Czech Republic</option>
|
||||
<option value="DK">Denmark</option>
|
||||
<option value="DJ">Djibouti</option>
|
||||
<option value="DM">Dominica</option>
|
||||
<option value="DO">Dominican Republic</option>
|
||||
<option value="EC">Ecuador</option>
|
||||
<option value="EG">Egypt</option>
|
||||
<option value="SV">El Salvador</option>
|
||||
<option value="GQ">Equatorial Guinea</option>
|
||||
<option value="ER">Eritrea</option>
|
||||
<option value="EE">Estonia</option>
|
||||
<option value="ET">Ethiopia</option>
|
||||
<option value="FK">Falkland Islands (Malvinas)</option>
|
||||
<option value="FO">Faroe Islands</option>
|
||||
<option value="FJ">Fiji</option>
|
||||
<option value="FI">Finland</option>
|
||||
<option value="FR">France</option>
|
||||
<option value="GF">French Guiana</option>
|
||||
<option value="PF">French Polynesia</option>
|
||||
<option value="TF">French Southern Territories</option>
|
||||
<option value="GA">Gabon</option>
|
||||
<option value="GM">Gambia</option>
|
||||
<option value="GE">Georgia</option>
|
||||
<option value="DE">Germany</option>
|
||||
<option value="GH">Ghana</option>
|
||||
<option value="GI">Gibraltar</option>
|
||||
<option value="GR">Greece</option>
|
||||
<option value="GL">Greenland</option>
|
||||
<option value="GD">Grenada</option>
|
||||
<option value="GP">Guadeloupe</option>
|
||||
<option value="GU">Guam</option>
|
||||
<option value="GT">Guatemala</option>
|
||||
<option value="GG">Guernsey</option>
|
||||
<option value="GN">Guinea</option>
|
||||
<option value="GW">Guinea-Bissau</option>
|
||||
<option value="GY">Guyana</option>
|
||||
<option value="HT">Haiti</option>
|
||||
<option value="HM">Heard Island and McDonald Islands</option>
|
||||
<option value="VA">Holy See (Vatican City State)</option>
|
||||
<option value="HN">Honduras</option>
|
||||
<option value="HK">Hong Kong</option>
|
||||
<option value="HU">Hungary</option>
|
||||
<option value="IS">Iceland</option>
|
||||
<option value="IN">India</option>
|
||||
<option value="ID">Indonesia</option>
|
||||
<option value="IR">Iran, Islamic Republic of</option>
|
||||
<option value="IQ">Iraq</option>
|
||||
<option value="IE">Ireland</option>
|
||||
<option value="IM">Isle of Man</option>
|
||||
<option value="IL">Israel</option>
|
||||
<option value="IT">Italy</option>
|
||||
<option value="JM">Jamaica</option>
|
||||
<option value="JP">Japan</option>
|
||||
<option value="JE">Jersey</option>
|
||||
<option value="JO">Jordan</option>
|
||||
<option value="KZ">Kazakhstan</option>
|
||||
<option value="KE">Kenya</option>
|
||||
<option value="KI">Kiribati</option>
|
||||
<option value="KP">Korea, Democratic People's Republic of</option>
|
||||
<option value="KR">Korea, Republic of</option>
|
||||
<option value="KW">Kuwait</option>
|
||||
<option value="KG">Kyrgyzstan</option>
|
||||
<option value="LA">Lao People's Democratic Republic</option>
|
||||
<option value="LV">Latvia</option>
|
||||
<option value="LB">Lebanon</option>
|
||||
<option value="LS">Lesotho</option>
|
||||
<option value="LR">Liberia</option>
|
||||
<option value="LY">Libya</option>
|
||||
<option value="LI">Liechtenstein</option>
|
||||
<option value="LT">Lithuania</option>
|
||||
<option value="LU">Luxembourg</option>
|
||||
<option value="MO">Macao</option>
|
||||
<option value="MK">Macedonia, the former Yugoslav Republic of</option>
|
||||
<option value="MG">Madagascar</option>
|
||||
<option value="MW">Malawi</option>
|
||||
<option value="MY">Malaysia</option>
|
||||
<option value="MV">Maldives</option>
|
||||
<option value="ML">Mali</option>
|
||||
<option value="MT">Malta</option>
|
||||
<option value="MH">Marshall Islands</option>
|
||||
<option value="MQ">Martinique</option>
|
||||
<option value="MR">Mauritania</option>
|
||||
<option value="MU">Mauritius</option>
|
||||
<option value="YT">Mayotte</option>
|
||||
<option value="MX">Mexico</option>
|
||||
<option value="FM">Micronesia, Federated States of</option>
|
||||
<option value="MD">Moldova, Republic of</option>
|
||||
<option value="MC">Monaco</option>
|
||||
<option value="MN">Mongolia</option>
|
||||
<option value="ME">Montenegro</option>
|
||||
<option value="MS">Montserrat</option>
|
||||
<option value="MA">Morocco</option>
|
||||
<option value="MZ">Mozambique</option>
|
||||
<option value="MM">Myanmar</option>
|
||||
<option value="NA">Namibia</option>
|
||||
<option value="NR">Nauru</option>
|
||||
<option value="NP">Nepal</option>
|
||||
<option value="NL">Netherlands</option>
|
||||
<option value="NC">New Caledonia</option>
|
||||
<option value="NZ">New Zealand</option>
|
||||
<option value="NI">Nicaragua</option>
|
||||
<option value="NE">Niger</option>
|
||||
<option value="NG">Nigeria</option>
|
||||
<option value="NU">Niue</option>
|
||||
<option value="NF">Norfolk Island</option>
|
||||
<option value="MP">Northern Mariana Islands</option>
|
||||
<option value="NO">Norway</option>
|
||||
<option value="OM">Oman</option>
|
||||
<option value="PK">Pakistan</option>
|
||||
<option value="PW">Palau</option>
|
||||
<option value="PS">Palestinian Territory, Occupied</option>
|
||||
<option value="PA">Panama</option>
|
||||
<option value="PG">Papua New Guinea</option>
|
||||
<option value="PY">Paraguay</option>
|
||||
<option value="PE">Peru</option>
|
||||
<option value="PH">Philippines</option>
|
||||
<option value="PN">Pitcairn</option>
|
||||
<option value="PL">Poland</option>
|
||||
<option value="PT">Portugal</option>
|
||||
<option value="PR">Puerto Rico</option>
|
||||
<option value="QA">Qatar</option>
|
||||
<option value="RE">Réunion</option>
|
||||
<option value="RO">Romania</option>
|
||||
<option value="RU">Russian Federation</option>
|
||||
<option value="RW">Rwanda</option>
|
||||
<option value="BL">Saint Barthélemy</option>
|
||||
<option value="SH">Saint Helena, Ascension and Tristan da Cunha</option>
|
||||
<option value="KN">Saint Kitts and Nevis</option>
|
||||
<option value="LC">Saint Lucia</option>
|
||||
<option value="MF">Saint Martin (French part)</option>
|
||||
<option value="PM">Saint Pierre and Miquelon</option>
|
||||
<option value="VC">Saint Vincent and the Grenadines</option>
|
||||
<option value="WS">Samoa</option>
|
||||
<option value="SM">San Marino</option>
|
||||
<option value="ST">Sao Tome and Principe</option>
|
||||
<option value="SA">Saudi Arabia</option>
|
||||
<option value="SN">Senegal</option>
|
||||
<option value="RS">Serbia</option>
|
||||
<option value="SC">Seychelles</option>
|
||||
<option value="SL">Sierra Leone</option>
|
||||
<option value="SG">Singapore</option>
|
||||
<option value="SX">Sint Maarten (Dutch part)</option>
|
||||
<option value="SK">Slovakia</option>
|
||||
<option value="SI">Slovenia</option>
|
||||
<option value="SB">Solomon Islands</option>
|
||||
<option value="SO">Somalia</option>
|
||||
<option value="ZA">South Africa</option>
|
||||
<option value="GS">South Georgia and the South Sandwich Islands</option>
|
||||
<option value="SS">South Sudan</option>
|
||||
<option value="ES">Spain</option>
|
||||
<option value="LK">Sri Lanka</option>
|
||||
<option value="SD">Sudan</option>
|
||||
<option value="SR">Suriname</option>
|
||||
<option value="SJ">Svalbard and Jan Mayen</option>
|
||||
<option value="SZ">Swaziland</option>
|
||||
<option value="SE">Sweden</option>
|
||||
<option value="CH">Switzerland</option>
|
||||
<option value="SY">Syrian Arab Republic</option>
|
||||
<option value="TW">Taiwan, Province of China</option>
|
||||
<option value="TJ">Tajikistan</option>
|
||||
<option value="TZ">Tanzania, United Republic of</option>
|
||||
<option value="TH">Thailand</option>
|
||||
<option value="TL">Timor-Leste</option>
|
||||
<option value="TG">Togo</option>
|
||||
<option value="TK">Tokelau</option>
|
||||
<option value="TO">Tonga</option>
|
||||
<option value="TT">Trinidad and Tobago</option>
|
||||
<option value="TN">Tunisia</option>
|
||||
<option value="TR">Turkey</option>
|
||||
<option value="TM">Turkmenistan</option>
|
||||
<option value="TC">Turks and Caicos Islands</option>
|
||||
<option value="TV">Tuvalu</option>
|
||||
<option value="UG">Uganda</option>
|
||||
<option value="UA">Ukraine</option>
|
||||
<option value="AE">United Arab Emirates</option>
|
||||
<option value="GB">United Kingdom</option>
|
||||
<option value="US">United States</option>
|
||||
<option value="UM">United States Minor Outlying Islands</option>
|
||||
<option value="UY">Uruguay</option>
|
||||
<option value="UZ">Uzbekistan</option>
|
||||
<option value="VU">Vanuatu</option>
|
||||
<option value="VE">Venezuela, Bolivarian Republic of</option>
|
||||
<option value="VN">Viet Nam</option>
|
||||
<option value="VG">Virgin Islands, British</option>
|
||||
<option value="VI">Virgin Islands, U.S.</option>
|
||||
<option value="WF">Wallis and Futuna</option>
|
||||
<option value="EH">Western Sahara</option>
|
||||
<option value="YE">Yemen</option>
|
||||
<option value="ZM">Zambia</option>
|
||||
<option value="ZW">Zimbabwe</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form__col">
|
||||
<input class="input-text" type="tel" ng-model="dial" required placeholder="Mobile phone number" tabindex="5">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form__row">
|
||||
<input class="input-text" type="text" ng-model="betaCode" required placeholder="Beta access code" tabindex="6">
|
||||
|
@ -51,10 +51,27 @@ describe('Create Account Controller unit test', function() {
|
||||
expect(adminStub.createUser.called).to.be.false;
|
||||
});
|
||||
|
||||
it('should fail due to invalid phone number', function(done) {
|
||||
scope.form.$invalid = false;
|
||||
scope.betaCode = 'asfd';
|
||||
scope.region = 'DE';
|
||||
scope.dial = '0';
|
||||
|
||||
scope.createWhiteoutAccount().then(function() {
|
||||
expect(scope.busy).to.be.false;
|
||||
expect(scope.errMsg).to.match(/phone/);
|
||||
expect(adminStub.createUser.calledOnce).to.be.false;
|
||||
done();
|
||||
});
|
||||
|
||||
expect(scope.busy).to.be.true;
|
||||
});
|
||||
|
||||
it('should fail to error creating user', function(done) {
|
||||
scope.form.$invalid = false;
|
||||
scope.betaCode = 'asfd';
|
||||
scope.phone = '12345';
|
||||
scope.region = 'DE';
|
||||
scope.dial = '0160 12345678';
|
||||
adminStub.createUser.returns(rejects(new Error('asdf')));
|
||||
|
||||
scope.createWhiteoutAccount().then(function() {
|
||||
@ -70,7 +87,8 @@ describe('Create Account Controller unit test', function() {
|
||||
it('should work', function(done) {
|
||||
scope.form.$invalid = false;
|
||||
scope.betaCode = 'asfd';
|
||||
scope.phone = '12345';
|
||||
scope.region = 'DE';
|
||||
scope.dial = '0160 12345678';
|
||||
adminStub.createUser.returns(resolves());
|
||||
|
||||
scope.createWhiteoutAccount().then(function() {
|
||||
|
Loading…
Reference in New Issue
Block a user