Skip to content

Commit 2cabe5d

Browse files
committed
Fix bug with country code
1 parent 9bfeb15 commit 2cabe5d

File tree

6 files changed

+75
-52
lines changed

6 files changed

+75
-52
lines changed

android/app/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ android {
5151
}
5252

5353
dependencies {
54-
implementation platform('com.google.firebase:firebase-bom:33.5.1')
54+
implementation platform('com.google.firebase:firebase-bom:33.13.0')
5555
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
5656
implementation 'com.google.firebase:firebase-analytics-ktx'
5757
implementation 'com.google.firebase:firebase-messaging-ktx'
@@ -66,6 +66,7 @@ dependencies {
6666
implementation 'org.apache.commons:commons-text:1.12.0'
6767
implementation 'com.google.android.material:material:1.12.0'
6868
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
69+
implementation 'com.googlecode.libphonenumber:libphonenumber:9.0.4'
6970
implementation 'androidx.core:core-ktx:1.15.0'
7071
testImplementation 'junit:junit:4.13.2'
7172
androidTestImplementation 'androidx.test.ext:junit:1.2.1'

android/app/src/main/java/com/httpsms/HttpSmsApiService.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,11 @@ class HttpSmsApiService(private val apiKey: String, private val baseURL: URI) {
217217
if (!response.isSuccessful) {
218218
Timber.e("error response [${response.body?.string()}] with code [${response.code}] while updating FCM token [$fcmToken] with apiKey [$apiKey]")
219219
response.close()
220-
return Triple(null,"Cannot validate the API key. Check if it is correct and try again.", null)
220+
if (response.code == 401) {
221+
Timber.e("invalid API key [$apiKey]")
222+
return Triple(null, "Cannot validate the API key. Check if it is correct and try again.", null)
223+
}
224+
return Triple(null,null, "Cannot login to the server, Make sure the phone number is in international format e.g +18005550100")
221225
}
222226

223227
Timber.i("FCM token submitted correctly with API key [$apiKey] and server url [$baseURL]" )

android/app/src/main/java/com/httpsms/LoginActivity.kt

Lines changed: 27 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import android.content.Intent
77
import android.content.pm.PackageManager
88
import android.os.Build
99
import android.os.Bundle
10-
import android.telephony.PhoneNumberUtils
1110
import android.telephony.TelephonyManager
1211
import android.view.View
1312
import android.webkit.URLUtil
@@ -23,6 +22,7 @@ import com.google.android.material.button.MaterialButton
2322
import com.google.android.material.progressindicator.LinearProgressIndicator
2423
import com.google.android.material.textfield.TextInputEditText
2524
import com.google.android.material.textfield.TextInputLayout
25+
import com.httpsms.validators.PhoneNumberValidator
2626
import com.journeyapps.barcodescanner.ScanContract
2727
import com.journeyapps.barcodescanner.ScanOptions
2828
import timber.log.Timber
@@ -180,15 +180,15 @@ class LoginActivity : AppCompatActivity() {
180180
Timber.d("login button clicked")
181181

182182
val error = isGooglePlayServicesAvailable()
183-
if (error != null || Settings.getFcmToken(this) == null) {
183+
if (error != null) {
184184
Timber.d("google play services not installed [${error}]")
185185
Toast.makeText(this, error, Toast.LENGTH_SHORT).show()
186186
return
187187
}
188188

189189
if (Settings.getFcmToken(this) == null) {
190190
Timber.d("The FCM token is not set")
191-
Toast.makeText(this, "Cannot find FCM token. Make sure you have google play services installed", Toast.LENGTH_LONG).show()
191+
Toast.makeText(this, "Cannot find FCM token. Make sure you have Google Play Services installed", Toast.LENGTH_LONG).show()
192192
return
193193
}
194194

@@ -220,6 +220,8 @@ class LoginActivity : AppCompatActivity() {
220220
val phoneNumberSIM2 = findViewById<TextInputEditText>(R.id.loginPhoneNumberInputSIM2)
221221
phoneNumberSIM2.isEnabled = false
222222

223+
val countryCode = getCountryCode()
224+
223225
val resetView = fun () {
224226
apiKey.isEnabled = true
225227
serverUrl.isEnabled = true
@@ -229,25 +231,17 @@ class LoginActivity : AppCompatActivity() {
229231
loginButton().isEnabled = true
230232
}
231233

232-
if (
233-
!PhoneNumberUtils.isWellFormedSmsAddress(phoneNumber.text.toString().trim()) ||
234-
!PhoneNumberUtils.isGlobalPhoneNumber(phoneNumber.text.toString().trim())
235-
) {
234+
if (!PhoneNumberValidator.isValidPhoneNumber(phoneNumber.text.toString().trim(), countryCode)) {
236235
Timber.e("[SIM1] phone number [${phoneNumber.text.toString()}] is not valid")
237236
resetView()
238-
phoneNumberLayout.error = "Invalid E.164 phone number"
237+
phoneNumberLayout.error = "Enter an international phone number in the E.164 format"
239238
return
240239
}
241240

242-
if (
243-
SmsManagerService.isDualSIM(this) && (
244-
!PhoneNumberUtils.isWellFormedSmsAddress(phoneNumberSIM2.text.toString().trim()) ||
245-
!PhoneNumberUtils.isGlobalPhoneNumber(phoneNumberSIM2.text.toString().trim())
246-
)
247-
) {
241+
if (SmsManagerService.isDualSIM(this) && !PhoneNumberValidator.isValidPhoneNumber(phoneNumberSIM2.text.toString().trim(), countryCode)) {
248242
Timber.e("[SIM2] phone number [${phoneNumberSIM2.text.toString()}] is not valid")
249243
resetView()
250-
phoneNumberLayoutSIM2.error = "Invalid E.164 phone number"
244+
phoneNumberLayoutSIM2.error = "Enter an international phone number in the E.164 format"
251245
return
252246
}
253247

@@ -284,11 +278,11 @@ class LoginActivity : AppCompatActivity() {
284278
Settings.setApiKeyAsync(this, apiKey.text.toString())
285279
Settings.setServerUrlAsync(this, serverUrl.text.toString().trim())
286280

287-
val e164PhoneNumber = formatE164(phoneNumber.text.toString().trim())
281+
val e164PhoneNumber = PhoneNumberValidator.formatE164(phoneNumber.text.toString().trim(), countryCode)
288282
Settings.setSIM1PhoneNumber(this, e164PhoneNumber)
289283

290284
if(SmsManagerService.isDualSIM(this)) {
291-
val sim2PhoneNumber = formatE164(phoneNumberSIM2.text.toString().trim())
285+
val sim2PhoneNumber = PhoneNumberValidator.formatE164(phoneNumberSIM2.text.toString().trim(), countryCode)
292286
Settings.setSIM2PhoneNumber(this, sim2PhoneNumber)
293287
}
294288

@@ -300,7 +294,7 @@ class LoginActivity : AppCompatActivity() {
300294
Thread {
301295
val service = HttpSmsApiService(apiKey.text.toString(), URI(serverUrl.text.toString().trim()))
302296

303-
var e164PhoneNumber = formatE164(phoneNumber.text.toString().trim())
297+
var e164PhoneNumber = PhoneNumberValidator.formatE164(phoneNumber.text.toString().trim(), countryCode)
304298
var response = service.updateFcmToken(e164PhoneNumber, Constants.SIM1, Settings.getFcmToken(this) ?: "")
305299
if(response.second != null || response.third != null) {
306300
Timber.e("error updating fcm token [${response.second}], third [${response.third}]")
@@ -314,41 +308,14 @@ class LoginActivity : AppCompatActivity() {
314308
return@Thread
315309
}
316310

317-
e164PhoneNumber = formatE164(phoneNumberSIM2.text.toString().trim())
311+
e164PhoneNumber = PhoneNumberValidator.formatE164(phoneNumberSIM2.text.toString().trim(), countryCode)
318312
response = service.updateFcmToken(e164PhoneNumber, Constants.SIM2, Settings.getFcmToken(this) ?: "")
319313

320314
liveData.postValue(Pair(response.second, response.third))
321315
Timber.d("finished validating api URL")
322316
}.start()
323317
}
324318

325-
private fun formatE164(number: String): String {
326-
var phoneNumber = number.trim()
327-
if (!number.startsWith("+")) {
328-
phoneNumber = "+$number"
329-
}
330-
331-
Timber.d("formatting phone number [${phoneNumber}] into e164")
332-
333-
val formattedNumber = PhoneNumberUtils.formatNumberToE164(
334-
phoneNumber,
335-
this.resources.configuration.locales.get(0).country
336-
)
337-
338-
if (formattedNumber !== null) {
339-
return formattedNumber
340-
}
341-
342-
return phoneNumber;
343-
}
344-
345-
private fun addPlus(number: String): String {
346-
if (number.startsWith("+")) {
347-
return number
348-
}
349-
return "+$number"
350-
}
351-
352319
private fun redirectToMain() {
353320
if (!Settings.isLoggedIn(this)) {
354321
return
@@ -362,4 +329,18 @@ class LoginActivity : AppCompatActivity() {
362329
private fun loginButton(): MaterialButton {
363330
return findViewById(R.id.loginButton)
364331
}
332+
333+
private fun getCountryCode() : String {
334+
// Get the TelephonyManager from the system services
335+
val tm = this.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
336+
337+
// Get the network country ISO code and convert it to uppercase
338+
val code = tm.networkCountryIso.uppercase()
339+
340+
// If the country code is empty, retrieve the country code from the device's locale
341+
if (code.isEmpty()) {
342+
return this.resources.configuration.locales.get(0).country.uppercase()
343+
}
344+
return code
345+
}
365346
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.httpsms.validators
2+
3+
import com.google.i18n.phonenumbers.PhoneNumberUtil
4+
import timber.log.Timber
5+
6+
class PhoneNumberValidator {
7+
companion object {
8+
private val phoneNumberUtil = PhoneNumberUtil.getInstance()
9+
fun isValidPhoneNumber(phoneNumber: String, countryCode: String): Boolean {
10+
Timber.e(countryCode)
11+
return try {
12+
if (phoneNumber.isEmpty()) {
13+
return false
14+
}
15+
val number = phoneNumberUtil.parse(fixNumber(phoneNumber), countryCode)
16+
phoneNumberUtil.isValidNumber(number)
17+
} catch (e: Exception) {
18+
false
19+
}
20+
}
21+
fun formatE164(phoneNumber: String, countryCode: String): String {
22+
return try {
23+
val number = phoneNumberUtil.parse(fixNumber(phoneNumber), countryCode)
24+
phoneNumberUtil.format(number, PhoneNumberUtil.PhoneNumberFormat.E164)
25+
} catch (e: Exception) {
26+
phoneNumber
27+
}
28+
}
29+
30+
private fun fixNumber(phoneNumber: String): String {
31+
if (phoneNumber.length >= 11 && !phoneNumber.startsWith("+")) {
32+
return "+${phoneNumber}"
33+
}
34+
return phoneNumber
35+
}
36+
}
37+
}

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22
buildscript {
33
ext {
4-
kotlin_version = '1.9.10'
4+
kotlin_version = '2.1.0'
55
}
66
repositories {
77
// Check that you have the following line (if not, add it):

api/pkg/validators/validator.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ func init() {
2929
govalidator.AddCustomRule(phoneNumberRule, func(field string, rule string, message string, value interface{}) error {
3030
phoneNumber, ok := value.(string)
3131
if !ok {
32-
return fmt.Errorf("The %s field must be a valid E.164 phone number: https://en.wikipedia.org/wiki/E.164", field)
32+
return fmt.Errorf("The %s field must be a valid E.164 phone number in the international format e.g +18005550100", field)
3333
}
3434

3535
_, err := phonenumbers.Parse(phoneNumber, phonenumbers.UNKNOWN_REGION)
3636
if err != nil {
37-
return fmt.Errorf("The %s field must be a valid E.164 phone number: https://en.wikipedia.org/wiki/E.164", field)
37+
return fmt.Errorf("The %s field must be a valid E.164 phone number in the international format e.g +18005550100", field)
3838
}
3939

4040
return nil
@@ -49,7 +49,7 @@ func init() {
4949
for index, number := range phoneNumbers {
5050
_, err := phonenumbers.Parse(number, phonenumbers.UNKNOWN_REGION)
5151
if err != nil {
52-
return fmt.Errorf("The %s field in index [%d] must be a valid E.164 phone number: https://en.wikipedia.org/wiki/E.164", field, index)
52+
return fmt.Errorf("The %s field in index [%d] must be a valid E.164 phone number in the international format e.g +18005550100", field, index)
5353
}
5454
}
5555

0 commit comments

Comments
 (0)