Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(authenticator): make phone number mandatory when "required" option is specified #5794

Draft
wants to merge 28 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3a98a38
added checks for country code against the maximum length of number in…
Sep 27, 2024
3d8f70e
added a map of dial codes to number lengths, and check the input phon…
Sep 30, 2024
4173bba
removed files from building example app
Oct 1, 2024
259f4eb
removed files from \sandbox
Oct 1, 2024
8ef9d66
removed files from sandbox
Oct 1, 2024
d765390
updating formatting
Oct 1, 2024
184b10c
added checks for country code against the maximum length of number in…
Sep 27, 2024
0332e29
added a map of dial codes to number lengths, and check the input phon…
Sep 30, 2024
9f0439a
removed files from building example app
Oct 1, 2024
7da3d51
removed files from \sandbox
Oct 1, 2024
3d28992
removed files from sandbox
Oct 1, 2024
9d9498a
updating formatting
Oct 1, 2024
c616675
rewrote functions for better code standards, and rewrote duplicated test
ekjotmultani Jan 4, 2025
6d36e60
Merge branch 'fix/authenticator/phone-validator' of https://github.co…
ekjotmultani Jan 5, 2025
31a91cf
added checks for country code against the maximum length of number in…
Sep 27, 2024
ba417be
added a map of dial codes to number lengths, and check the input phon…
Sep 30, 2024
c157f28
removed files from building example app
Oct 1, 2024
08b3b54
removed files from \sandbox
Oct 1, 2024
faef952
removed files from sandbox
Oct 1, 2024
94c2bb4
updating formatting
Oct 1, 2024
23e0c1c
added checks for country code against the maximum length of number in…
Sep 27, 2024
babdfb5
added a map of dial codes to number lengths, and check the input phon…
Sep 30, 2024
0d6733e
removed files from building example app
Oct 1, 2024
a6987d9
removed files from \sandbox
Oct 1, 2024
6460570
removed files from sandbox
Oct 1, 2024
5542a44
updating formatting
Oct 1, 2024
d954252
Merge branch 'fix/authenticator/phone-validator' of https://github.co…
ekjotmultani Jan 6, 2025
74dff61
Merge branch 'main' into fix/authenticator/phone-validator
ekjotmultani Jan 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:amplify_authenticator/src/keys.dart';
import 'package:amplify_authenticator/src/l10n/dial_code_resolver.dart';
import 'package:amplify_authenticator/src/utils/breakpoint.dart';
import 'package:amplify_authenticator/src/utils/dial_code.dart';
import 'package:amplify_authenticator/src/utils/dial_code_to_length.dart';
import 'package:amplify_authenticator/src/widgets/authenticator_input_config.dart';
import 'package:amplify_authenticator/src/widgets/form_field.dart';
import 'package:collection/collection.dart';
Expand Down Expand Up @@ -47,12 +48,22 @@ mixin AuthenticatorPhoneFieldMixin<FieldType extends Enum,
return phoneNumber?.ensureStartsWith('+${state.dialCode.value}');
}

String displayPhoneNumber(String phoneNumber) {
String displayPhoneNumber(String? phoneNumber) {
phoneNumber = phoneNumber ?? '';
final prefix = '+${state.dialCode.value}';
if (phoneNumber.startsWith(prefix)) {
phoneNumber = phoneNumber.substring(prefix.length);
}
return phoneNumber;
// this is to handle the case where the user may errantly input their dial code again in their phone number
// we make sure the user's phone number doesn't naturally just start with their dial code by checking if the number exceeds the maximum phone length of the country's phone number scheme before truncating it
if (!phoneNumber.startsWith(prefix.substring(1))) {
return phoneNumber;
}
final prefixLength = countryPhoneNumberLengths[prefix];
if (prefixLength == null || phoneNumber.length <= prefixLength) {
return phoneNumber;
}
return phoneNumber.substring(prefix.length - 1);
}

String get dialCode {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_authenticator/amplify_authenticator.dart';
import 'package:amplify_authenticator/src/keys.dart';
import 'package:amplify_authenticator/src/models/username_input.dart';
import 'package:amplify_authenticator/src/utils/dial_code_to_length.dart';
import 'package:amplify_authenticator/src/utils/validators.dart';
import 'package:amplify_authenticator/src/widgets/component.dart';
import 'package:amplify_authenticator/src/widgets/form_field.dart';
Expand Down Expand Up @@ -164,6 +165,58 @@ mixin AuthenticatorUsernameField<FieldType extends Enum,
}
}

String displayPhoneNumber(String? phoneNumber) {
phoneNumber = phoneNumber ?? '';
final prefix = '+${state.dialCode.value}';
if (phoneNumber.startsWith(prefix)) {
phoneNumber = phoneNumber.substring(prefix.length);
}
// this is to handle the case where the user may errantly input their dial code again in their phone number
// we make sure the user's phone number doesn't naturally just start with their dial code by checking if the number exceeds the maximum phone length of the country's phone number scheme before truncating it
if (phoneNumber.startsWith(prefix.substring(1))) {
if (countryPhoneNumberLengths.containsKey(prefix) &&
phoneNumber.length > countryPhoneNumberLengths[prefix]!) {
phoneNumber = phoneNumber.substring(prefix.length - 1);
}
}
return phoneNumber;
}

String displayPhoneNumber(String? phoneNumber) {
phoneNumber = phoneNumber ?? '';
final prefix = '+${state.dialCode.value}';
if (phoneNumber.startsWith(prefix)) {
phoneNumber = phoneNumber.substring(prefix.length);
}
// this is to handle the case where the user may errantly input their dial code again in their phone number
// we make sure the user's phone number doesn't naturally just start with their dial code by checking if the number exceeds the maximum phone length of the country's phone number scheme before truncating it
if (phoneNumber.startsWith(prefix.substring(1))) {
if (countryPhoneNumberLengths.containsKey(prefix) &&
phoneNumber.length > countryPhoneNumberLengths[prefix]!) {
phoneNumber = phoneNumber.substring(prefix.length - 1);
}
}
return phoneNumber;
}

String displayPhoneNumber(String? phoneNumber) {
phoneNumber = phoneNumber ?? '';
final prefix = '+${state.dialCode.value}';
if (phoneNumber.startsWith(prefix)) {
phoneNumber = phoneNumber.substring(prefix.length);
}
// this is to handle the case where the user may errantly input their dial code again in their phone number
// we make sure the user's phone number doesn't naturally just start with their dial code by checking if the number exceeds the maximum phone length of the country's phone number scheme before truncating it
if (!phoneNumber.startsWith(prefix.substring(1))) {
return phoneNumber;
}
final prefixLength = countryPhoneNumberLengths[prefix];
if (prefixLength == null || phoneNumber.length <= prefixLength) {
return phoneNumber;
}
return phoneNumber.substring(prefix.length - 1);
}

@override
FormFieldValidator<UsernameInput> get validator {
switch (selectedUsernameType) {
Expand All @@ -183,7 +236,7 @@ mixin AuthenticatorUsernameField<FieldType extends Enum,
isOptional: isOptional,
context: context,
inputResolver: stringResolver.inputs,
)(input?.username);
)(displayPhoneNumber(input?.username));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
/// A list of [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1) dial codes mapped to the maximum [possible length](https://en.wikipedia.org/wiki/National_conventions_for_writing_telephone_numbers) of the phone number from that country as an integer
///
///
Map<String, int> countryPhoneNumberLengths = {
'+1': 10, // United States, Canada, and other NANP countries
'+7': 10, // Russia, Kazakhstan
'+20': 10, // Egypt
'+27': 9, // South Africa
'+30': 10, // Greece
'+31': 9, // Netherlands
'+32': 9, // Belgium
'+33': 9, // France
'+34': 9, // Spain
'+36': 9, // Hungary
'+39': 10, // Italy
'+40': 9, // Romania
'+44': 10, // United Kingdom
'+45': 8, // Denmark
'+46': 9, // Sweden
'+47': 8, // Norway
'+48': 9, // Poland
'+49': 11, // Germany
'+51': 9, // Peru
'+52': 10, // Mexico
'+53': 8, // Cuba
'+54': 10, // Argentina
'+55': 11, // Brazil
'+56': 9, // Chile
'+57': 10, // Colombia
'+58': 10, // Venezuela
'+60': 10, // Malaysia
'+61': 9, // Australia
'+62': 11, // Indonesia
'+63': 10, // Philippines
'+64': 9, // New Zealand
'+65': 8, // Singapore
'+66': 9, // Thailand
'+81': 10, // Japan
'+82': 10, // South Korea
'+84': 10, // Vietnam
'+86': 11, // China
'+90': 11, // Turkey
'+91': 10, // India
'+92': 10, // Pakistan
'+93': 9, // Afghanistan
'+94': 10, // Sri Lanka
'+95': 9, // Myanmar
'+98': 10, // Iran
'+211': 9, // South Sudan
'+212': 9, // Morocco
'+213': 9, // Algeria
'+216': 8, // Tunisia
'+218': 10, // Libya
'+220': 7, // Gambia
'+221': 9, // Senegal
'+222': 9, // Mauritania
'+223': 8, // Mali
'+224': 9, // Guinea
'+225': 10, // Ivory Coast
'+226': 8, // Burkina Faso
'+227': 8, // Niger
'+228': 8, // Togo
'+229': 8, // Benin
'+230': 7, // Mauritius
'+231': 9, // Liberia
'+232': 8, // Sierra Leone
'+233': 9, // Ghana
'+234': 10, // Nigeria
'+235': 8, // Chad
'+236': 8, // Central African Republic
'+237': 9, // Cameroon
'+238': 7, // Cape Verde
'+239': 7, // São Tomé and Príncipe
'+240': 9, // Equatorial Guinea
'+241': 9, // Gabon
'+242': 9, // Republic of the Congo
'+243': 9, // DR Congo
'+244': 9, // Angola
'+245': 7, // Guinea-Bissau
'+248': 7, // Seychelles
'+249': 9, // Sudan
'+250': 9, // Rwanda
'+251': 9, // Ethiopia
'+252': 8, // Somalia
'+253': 8, // Djibouti
'+254': 10, // Kenya
'+255': 9, // Tanzania
'+256': 9, // Uganda
'+257': 8, // Burundi
'+258': 9, // Mozambique
'+260': 9, // Zambia
'+261': 9, // Madagascar
'+262': 9, // Réunion
'+263': 9, // Zimbabwe
'+264': 9, // Namibia
'+265': 9, // Malawi
'+266': 8, // Lesotho
'+267': 8, // Botswana
'+268': 8, // Eswatini (Swaziland)
'+269': 7, // Comoros
'+290': 4, // Saint Helena
'+291': 7, // Eritrea
'+297': 7, // Aruba
'+298': 6, // Faroe Islands
'+299': 6, // Greenland
'+350': 8, // Gibraltar
'+351': 9, // Portugal
'+352': 9, // Luxembourg
'+353': 9, // Ireland
'+354': 7, // Iceland
'+355': 9, // Albania
'+356': 8, // Malta
'+357': 8, // Cyprus
'+358': 10, // Finland
'+359': 9, // Bulgaria
'+370': 8, // Lithuania
'+371': 8, // Latvia
'+372': 8, // Estonia
'+373': 8, // Moldova
'+374': 8, // Armenia
'+375': 9, // Belarus
'+376': 6, // Andorra
'+377': 8, // Monaco
'+378': 10, // San Marino
'+380': 9, // Ukraine
'+381': 9, // Serbia
'+382': 9, // Montenegro
'+385': 9, // Croatia
'+386': 9, // Slovenia
'+387': 8, // Bosnia and Herzegovina
'+389': 8, // North Macedonia
'+420': 9, // Czech Republic
'+421': 9, // Slovakia
'+423': 7, // Liechtenstein
'+500': 5, // Falkland Islands
'+501': 7, // Belize
'+502': 8, // Guatemala
'+503': 8, // El Salvador
'+504': 8, // Honduras
'+505': 8, // Nicaragua
'+506': 8, // Costa Rica
'+507': 7, // Panama
'+509': 8, // Haiti
'+590': 9, // Guadeloupe
'+591': 8, // Bolivia
'+592': 7, // Guyana
'+593': 9, // Ecuador
'+594': 9, // French Guiana
'+595': 9, // Paraguay
'+596': 9, // Martinique
'+597': 7, // Suriname
'+598': 9, // Uruguay
'+670': 7, // East Timor
'+672': 6, // Australian External Territories
'+673': 7, // Brunei
'+674': 7, // Nauru
'+675': 8, // Papua New Guinea
'+676': 5, // Tonga
'+677': 7, // Solomon Islands
'+678': 7, // Vanuatu
'+679': 7, // Fiji
'+680': 7, // Palau
'+681': 6, // Wallis and Futuna
'+682': 5, // Cook Islands
'+683': 4, // Niue
'+685': 7, // Samoa
'+686': 8, // Kiribati
'+687': 6, // New Caledonia
'+688': 5, // Tuvalu
'+689': 6, // French Polynesia
'+690': 4, // Tokelau
'+691': 7, // Micronesia
'+692': 7, // Marshall Islands
'+850': 10, // North Korea
'+852': 8, // Hong Kong
'+853': 8, // Macau
'+855': 9, // Cambodia
'+856': 9, // Laos
'+880': 10, // Bangladesh
'+886': 9, // Taiwan
'+960': 7, // Maldives
'+961': 8, // Lebanon
'+962': 9, // Jordan
'+963': 9, // Syria
'+964': 10, // Iraq
'+965': 8, // Kuwait
'+966': 9, // Saudi Arabia
'+967': 9, // Yemen
'+968': 8, // Oman
'+970': 9, // Palestine
'+971': 9, // United Arab Emirates
'+972': 9, // Israel
'+973': 8, // Bahrain
'+974': 8, // Qatar
'+975': 8, // Bhutan
'+976': 8, // Mongolia
'+977': 10, // Nepal
'+992': 9, // Tajikistan
'+993': 8, // Turkmenistan
'+994': 9, // Azerbaijan
'+995': 9, // Georgia
'+996': 9, // Kyrgyzstan
'+998': 9, // Uzbekistan
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'package:flutter/material.dart';
*/
final usernameRegex = RegExp(r'^\S+$');
final emailRegex = RegExp(r'^\S+@\S+$');
final phoneNumberRegex = RegExp(r'^\+\d+$');
final phoneNumberRegex = RegExp(r'^\d+$');
final _codeRegex = RegExp(r'^\d{6}$');
final _uppercase = RegExp(r'[A-Z]');
final _lowercase = RegExp(r'[a-z]');
Expand Down Expand Up @@ -154,8 +154,8 @@ FormFieldValidator<String> validatePhoneNumber({
InputResolverKey.phoneNumberEmpty,
);
}
phoneNumber = phoneNumber.trim();
if (!phoneNumberRegex.hasMatch(phoneNumber)) {
final formattedNumber = phoneNumber.trim();
if (!phoneNumberRegex.hasMatch(formattedNumber)) {
return inputResolver.resolve(context, InputResolverKey.phoneNumberFormat);
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ class _ConfirmSignInPhoneFieldState extends _ConfirmSignInTextFieldState
@override
FormFieldValidator<String> get validator {
return (phoneNumber) {
phoneNumber = formatPhoneNumber(phoneNumber);
phoneNumber = displayPhoneNumber(phoneNumber);
return validatePhoneNumber(
inputResolver: stringResolver.inputs,
context: context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,12 @@ class _AuthenticatorPhoneFieldState<FieldType extends Enum>
@override
FormFieldValidator<String> get validator {
return (String? phoneNumber) {
phoneNumber = formatPhoneNumber(phoneNumber);
final validator = widget.validator;
if (validator != null) {
phoneNumber = formatPhoneNumber(phoneNumber);
return validator(phoneNumber);
}
phoneNumber = displayPhoneNumber(phoneNumber);
return validatePhoneNumber(
inputResolver: stringResolver.inputs,
context: context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@ class _SignUpPhoneFieldState extends _SignUpTextFieldState
@override
FormFieldValidator<String> get validator {
return (phoneNumber) {
phoneNumber = formatPhoneNumber(phoneNumber);
phoneNumber = displayPhoneNumber(phoneNumber);
return validatePhoneNumber(
inputResolver: stringResolver.inputs,
context: context,
Expand Down
Loading
Loading