Enhance MFA multi-device testing on troubleshoot and revoke pages#84016
Enhance MFA multi-device testing on troubleshoot and revoke pages#84016chuckdries merged 53 commits intoExpensify:mainfrom
Conversation
- Fix ESLint prefer-at error in en.ts (use .at() instead of bracket notation)
- Fix type error in API types by using RevokeMultifactorAuthenticationCredentialsParams
- Add missing translation keys to all non-English language files:
- biometricsTest: statusNotRegistered, statusRegisteredOtherDevice, statusRegisteredThisDevice
- revoke: thisDevice, otherDevices
- Add missing Spanish translations: statusNeverRegistered, confirmationPromptAll, ctaAll
- Fix Spanish troubleshootBiometricsStatus to use status param instead of registered
Co-authored-by: {"message":"Not Found","documentation_url":"https://docs.github.com/rest/issues/comments#get-an-issue-comment","status":"404"} <{"message":"Not Found","documentation_url":"https://docs.github.com/rest/issues/comments#get-an-issue-comment","status":"404"}@users.noreply.github.com>
The previous commit inadvertently changed Unicode quote characters in the French translation file, breaking Prettier parsing. This restores the original characters and re-adds only the missing translation keys. Co-authored-by: Rafe Colton <rafecolton@users.noreply.github.com>
|
@JakubKorytko All resolved/replied |
|
@DylanDylann I'm getting the same error on the German translation:
@MelvinBot can you please analyze the above issue and recommend a fix? A few specific instructions:
|
AnalysisRoot cause: The The script detects When it tries to inject these into the non-English language files, it finds that This affects ALL non-English language files, not just German — each one has the same manually-added arrow function. Fix: Remove the manually-added For Spanish (which the script can't auto-generate), the translation needs to be added back manually after the script runs. diff --git a/src/languages/de.ts b/src/languages/de.ts
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -699,7 +699,6 @@
statusNeverRegistered: 'Nie registriert',
statusNotRegistered: 'Nicht registriert',
- statusRegisteredOtherDevice: () => ({one: 'Weiteres Gerät registriert', other: 'Andere Geräte registriert'}),
statusRegisteredThisDevice: 'Registriert',
},
diff --git a/src/languages/es.ts b/src/languages/es.ts
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -555,7 +555,6 @@
statusNotRegistered: 'No registrado',
- statusRegisteredOtherDevice: () => ({one: 'Otro dispositivo registrado', other: 'Otros dispositivos registrados'}),
statusRegisteredThisDevice: 'Registrado',
},
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -701,7 +701,6 @@
statusNotRegistered: 'Non enregistré',
- statusRegisteredOtherDevice: () => ({one: 'Un autre appareil enregistré', other: 'Autres appareils enregistrés'}),
statusRegisteredThisDevice: 'Enregistré',
},
diff --git a/src/languages/it.ts b/src/languages/it.ts
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -699,7 +699,6 @@
statusNotRegistered: 'Non registrato',
- statusRegisteredOtherDevice: () => ({one: 'Un altro dispositivo registrato', other: 'Altri dispositivi registrati'}),
statusRegisteredThisDevice: 'Registrato',
},
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -698,7 +698,6 @@
statusNotRegistered: '未登録',
- statusRegisteredOtherDevice: () => ({one: '他のデバイスが登録済み', other: '他のデバイスが登録済み'}),
statusRegisteredThisDevice: '登録済み',
},
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -698,7 +698,6 @@
statusNotRegistered: 'Niet geregistreerd',
- statusRegisteredOtherDevice: () => ({one: 'Een ander apparaat geregistreerd', other: 'Andere apparaten geregistreerd'}),
statusRegisteredThisDevice: 'Geregistreerd',
},
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -698,7 +698,6 @@
statusNotRegistered: 'Nie zarejestrowano',
- statusRegisteredOtherDevice: () => ({one: 'Inne urządzenie zarejestrowane', other: 'Inne urządzenia zarejestrowane'}),
statusRegisteredThisDevice: 'Zarejestrowano',
},
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -697,7 +697,6 @@
statusNotRegistered: 'Não registrado',
- statusRegisteredOtherDevice: () => ({one: 'Outro dispositivo registrado', other: 'Outros dispositivos registrados'}),
statusRegisteredThisDevice: 'Registrado',
},
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -691,7 +691,6 @@
statusNotRegistered: '未注册',
- statusRegisteredOtherDevice: () => ({one: '另一台设备已注册', other: '其他设备已注册'}),
statusRegisteredThisDevice: '已注册',
},After applying this patch and re-running the translation script, the script will auto-generate // In src/languages/es.ts, inside biometricsTest:
statusRegisteredOtherDevice: () => ({one: 'Otro dispositivo registrado', other: 'Otros dispositivos registrados'}), |
|
@MelvinBot Removing statusRegisteredOtherDevice caused the TypeScript check to fail |
|
I investigated the failing typecheck — here's what I found: Root Cause: The new key Affected files (each needs
Fix: Add the Each language file needs its own translated version of this key, following the same plural function pattern used in statusRegisteredOtherDevice: () => ({one: 'Otro dispositivo registrado', other: 'Otros dispositivos registrados'}), |
dbfb6ad to
e3d2612
Compare
There was a problem hiding this comment.
Looks pretty good overall, small NAB
d0a9a7e to
85b8008
Compare
|
Failed Eslint on main, I will merge new main when it's resolved |
There was a problem hiding this comment.
Looks good; translation files appear to be in the correct state
Reviewer Checklist
Screenshots/VideosAndroid: Nativeimproved.revoke.android.mp4iOS: Nativeimproved.revoke.ios.mp4 |
|
🚧 @chuckdries 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/chuckdries in version: 9.3.36-0 🚀
|
|
🚀 Deployed to production by https://github.com/luacmartins in version: 9.3.36-10 🚀
|

Explanation of Change
Taking over #83488 from @rafecolton
Enhance troubleshooting and device revocation page to:
Fixed Issues
$ #83482
PROPOSAL:
Tests
Offline tests
N/A, online only
QA Steps
Same as tests
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.Screenshots/Videos
Screen.Recording.2026-03-04.at.18.37.40.mov
Screen.Recording.2026-03-04.at.18.40.14.mp4