Re-apply secure private personal details + fix address autocomplete and country auto-fill#91000
Conversation
…rm + magic code" This reverts commit 35c6afd.
Replace the plain TextInput for ADDRESS_LINE_1 in the unified private personal details form with AddressSearch (Google Places autocomplete), and map its selected place into the form's street/street2/city/state/zip/country inputs via renamedInputKeys so all sub-fields auto-fill on selection. Also read ONYXKEYS.COUNTRY (geolocation-derived) and use it as the initial value for the CountrySelector when the user has no saved address country.
|
@QichenZhu Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
This comment has been minimized.
This comment has been minimized.
Move both COUNTRY_ZIP_REGEX_DATA and GENERIC_ZIP_CODE_REGEX out of NewDot's local CONST and consume them from expensify-common instead, so OldDot can use the same per-country zip regex data for its card-replacement form. No behavior change. Co-authored-by: Cursor <cursoragent@cursor.com>
2.0.179 was never published to npm; the published version with COUNTRY_ZIP_REGEX_DATA / GENERIC_ZIP_CODE_REGEX is 2.0.180.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1db24a00fe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
🦜 Polyglot Parrot! 🦜Squawk! Looks like you added some shiny new English strings. Allow me to parrot them back to you in other tongues: View the translation diffdiff --git a/src/languages/de.ts b/src/languages/de.ts
index 8d563e6c..25b894ff 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -3307,7 +3307,7 @@ ${amount} für ${merchant} – ${date}`,
enterPhoneNumber: 'Wie lautet deine Telefonnummer?',
personalDetails: 'Persönliche Angaben',
privateDataMessage: 'Diese Angaben werden für Reisen und Zahlungen verwendet. Sie werden niemals in deinem öffentlichen Profil angezeigt.',
- basicDetails: 'Grundlegende Angaben',
+ basicDetails: 'Grundlegende Details',
legalName: 'Rechtlicher Name',
legalFirstName: 'Rechtlicher Vorname',
legalLastName: 'Rechtlicher Nachname',
@@ -3502,7 +3502,7 @@ ${amount} für ${merchant} – ${date}`,
noBankAccountSelected: 'Bitte wähle ein Konto aus',
taxID: 'Bitte geben Sie eine gültige Steueridentifikationsnummer ein',
website: 'Bitte eine gültige Website eingeben',
- zipCode: `Bitte gib eine gültige Postleitzahl im folgenden Format ein: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`,
+ zipCode: `Bitte geben Sie eine gültige Postleitzahl im folgenden Format ein: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`,
phoneNumber: 'Bitte gib eine gültige Telefonnummer ein',
email: 'Bitte gib eine gültige E-Mail-Adresse ein',
companyName: 'Bitte gib einen gültigen Unternehmensnamen ein',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 9916429e..6eca02ea 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -3184,7 +3184,7 @@ ${amount} para ${merchant} - ${date}`,
enterPhoneNumber: '¿Cuál es tu número de teléfono?',
personalDetails: 'Datos personales',
privateDataMessage: 'Estos detalles se utilizan para viajes y pagos. Nunca se mostrarán en tu perfil público.',
- basicDetails: 'Datos básicos',
+ basicDetails: 'Detalles básicos',
legalName: 'Nombre completo',
legalFirstName: 'Nombre legal',
legalLastName: 'Apellidos legales',
@@ -3382,7 +3382,7 @@ ${amount} para ${merchant} - ${date}`,
noBankAccountSelected: 'Por favor, elige una cuenta bancaria',
taxID: 'Por favor, introduce un número de identificación fiscal válido',
website: 'Por favor, introduce un sitio web válido',
- zipCode: `Formato de código postal incorrecto. Formato aceptable: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}.`,
+ zipCode: `Por favor, introduce un código ZIP válido usando el formato: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`,
phoneNumber: 'Por favor, introduce un teléfono válido',
email: 'Por favor, introduce una dirección de correo electrónico válida',
companyName: 'Por favor, introduce un nombre comercial legal válido',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 9733255b..71b0a13b 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -3313,7 +3313,7 @@ ${amount} pour ${merchant} - ${date}`,
enterPhoneNumber: 'Quel est votre numéro de téléphone ?',
personalDetails: 'Informations personnelles',
privateDataMessage: 'Ces informations sont utilisées pour les déplacements et les paiements. Elles ne s’affichent jamais sur votre profil public.',
- basicDetails: 'Détails de base',
+ basicDetails: 'Informations de base',
legalName: 'Nom légal',
legalFirstName: 'Prénom légal',
legalLastName: 'Nom de famille légal',
@@ -3511,7 +3511,7 @@ ${amount} pour ${merchant} - ${date}`,
noBankAccountSelected: 'Veuillez choisir un compte',
taxID: 'Veuillez saisir un numéro d’identification fiscale valide',
website: 'Veuillez saisir un site web valide',
- zipCode: `Veuillez saisir un code postal valide au format : ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`,
+ zipCode: `Veuillez saisir un code postal valide en utilisant le format : ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`,
phoneNumber: 'Veuillez saisir un numéro de téléphone valide',
email: 'Veuillez saisir une adresse e-mail valide',
companyName: 'Veuillez saisir un nom d’entreprise valide',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 5519ff9c..0a060339 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -3464,7 +3464,7 @@ ${integrationName === CONST.ONBOARDING_ACCOUNTING_MAPPING.other ? 'あなたの'
noBankAccountSelected: 'アカウントを選択してください',
taxID: '有効な納税者番号を入力してください',
website: '有効なウェブサイトを入力してください',
- zipCode: `有効なZIPコードを、次の形式で入力してください: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`,
+ zipCode: `有効な ZIP コードを、次の形式で入力してください: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`,
phoneNumber: '有効な電話番号を入力してください',
email: '有効なメールアドレスを入力してください',
companyName: '有効な会社名を入力してください',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index b0c5e6ce..45af6326 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -3481,7 +3481,7 @@ ${amount} dla ${merchant} - ${date}`,
noBankAccountSelected: 'Wybierz konto',
taxID: 'Wprowadź prawidłowy numer identyfikacji podatkowej',
website: 'Wprowadź prawidłową stronę internetową',
- zipCode: `Wprowadź prawidłowy kod ZIP w formacie: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`,
+ zipCode: `Wpisz poprawny kod ZIP w formacie: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`,
phoneNumber: 'Wprowadź prawidłowy numer telefonu',
email: 'Wpisz prawidłowy adres e‑mail',
companyName: 'Wprowadź prawidłową nazwę firmy',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 3830f2e4..53f2697d 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -3482,7 +3482,7 @@ ${amount} para ${merchant} - ${date}`,
noBankAccountSelected: 'Escolha uma conta',
taxID: 'Insira um número de identificação fiscal válido',
website: 'Insira um site válido',
- zipCode: `Insira um CEP válido usando o formato: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`,
+ zipCode: `Digite um CEP válido usando o formato: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`,
phoneNumber: 'Insira um número de telefone válido',
email: 'Insira um endereço de e-mail válido',
companyName: 'Insira um nome comercial válido',
Note You can apply these changes to your branch by copying the patch to your clipboard, then running |
📲 Install BuildsAndroid
|
- Extract resolveStateCode helper so the legacy state-name to 2-letter-code resolution lives in one place instead of being duplicated in the useState initializer and the CountrySelector onValueChange handler (CONSISTENCY-3). - Compare the submitted state against the normalized stored state in hasChanges(), so users with legacy full-name state values (e.g. "California") aren't routed to magic-code confirmation when nothing actually changed. - Persist the form values to the draft in onSubmit before navigating to the confirm page, so UI-prefilled fields the user never touched (geolocation country, normalized state) make it into the final UpdatePrivatePersonalDetails payload instead of falling back to the stored values.
|
@eVoloshchak Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppvideo_2026-05-21_18-09-37.mp4Android: mWeb ChromeScreen.Recording.2026-05-21.at.17.47.53.moviOS: HybridAppScreen.Recording.2026-05-21.at.17.33.53.moviOS: mWeb SafariScreen.Recording.2026-05-21.at.17.41.21.movMacOS: Chrome / SafariScreen.Recording.2026-05-21.at.16.58.22.mov |
…ersonalDetails-redo # Conflicts: # src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
rafecolton
left a comment
There was a problem hiding this comment.
Tested locally, it seems to work well. Address auto-complete is now working properly. @eVoloshchak please let me know when you are finished with the reviewer checklist 🙏
Yep, any change to any of those fields in that form should trigger the validate code form to come up |
…of github.com:Expensify/App into jasper-securePrivatePersonalDetails-redo
|
conflicts addressed |
|
🚧 @rafecolton has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by https://github.com/rafecolton in version: 9.3.81-0 🚀
|
|
Yes, help site changes are required. The PR consolidates separate Legal Name, Date of Birth, Phone Number, and Address pages into a single unified Private Personal Details form, adds magic code verification, and adds Google Places address autocomplete. I've created a draft PR with the necessary updates: #91597 Changes made:
The |
|
Deploy Blocker #91602 was identified to be related to this PR. |
|
Deploy Blocker #91604 was identified to be related to this PR. |
|
Deploy Blocker #91608 was identified to be related to this PR. |
|
Deploy Blocker #91611 was identified to be related to this PR. |
|
Dang, both of those look like legitimate bugs |
|
🚀 Deployed to production by https://github.com/luacmartins in version: 9.3.81-2 🚀
|
Explanation of Change
This re-applies the changes from #87928 (reverted via #90835) and additionally fixes the regression reported in #90834 on the unified Private Personal Details form:
TextInputforADDRESS_LINE_1inPrivatePersonalDetailsPagewith theAddressSearchcomponent (Google Places autocomplete), so the address suggestion list appears again while typing.renamedInputKeysso selecting an autocomplete suggestion auto-populatesstreet/street2/city/state/zip/country(the values land in the form's draft state via the FormProvider'sonInputChange, and the localselectedCountry/selectedStateReact state is updated through theonValueChangehandler so theCountrySelectorandStateSelectorreflect the chosen place).ONYXKEYS.COUNTRY(geolocation-derived) and use it as the initial value forselectedCountrywhen the user has no saved address country, restoring the geolocation-based default that existed inPersonalAddressPage.Depends on Auth PR and Web-Expensify PR (same as the original PR).
Fixed Issues
$ #90834
PROPOSAL:
Tests
Offline tests
QA Steps
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps./** comment above it */thisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor)thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari