[ECUK 3DS] Fix edge case re-enrolling a device when user has a different device currently enrolled#82606
Conversation
…econd device after revoking their credentials server-side
|
@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] |
src/components/MultifactorAuthentication/Context/usePromptContent.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 262c1e010a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
src/components/MultifactorAuthentication/Context/usePromptContent.ts
Outdated
Show resolved
Hide resolved
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
…ntialsKnownToServer directly
|
🚧 @rafecolton has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
🦜 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 4afeb1ea..5fbc6b1a 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -175,7 +175,6 @@ import type {
ZipCodeExampleFormatParams,
} from './params';
import type {TranslationDeepObject} from './types';
-
type StateValue = {
stateISO: string;
stateName: string;
@@ -720,6 +719,7 @@ const translations: TranslationDeepObject<typeof en> = {
noDevices: 'Sie haben keine Geräte für die Überprüfung per Gesicht/Fingerabdruck oder Passkey registriert. Wenn Sie welche registrieren, können Sie den Zugriff hier widerrufen.',
dismiss: 'Verstanden',
error: 'Anfrage fehlgeschlagen. Versuche es später noch einmal.',
+ revoke: 'Widerrufen',
},
unsupportedDevice: {
unsupportedDevice: 'Nicht unterstütztes Gerät',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 2be85924..0935cf7f 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -175,7 +175,6 @@ import type {
ZipCodeExampleFormatParams,
} from './params';
import type {TranslationDeepObject} from './types';
-
type StateValue = {
stateISO: string;
stateName: string;
@@ -724,6 +723,7 @@ const translations: TranslationDeepObject<typeof en> = {
'Vous n’avez enregistré aucun appareil pour la vérification par reconnaissance faciale, empreinte digitale ou passkey. Si vous en enregistrez, vous pourrez révoquer cet accès ici.',
dismiss: 'Compris',
error: 'La requête a échoué. Réessayez plus tard.',
+ revoke: 'Révoquer',
},
unsupportedDevice: {
unsupportedDevice: 'Appareil non pris en charge',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 670faea9..3f73a869 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -175,7 +175,6 @@ import type {
ZipCodeExampleFormatParams,
} from './params';
import type {TranslationDeepObject} from './types';
-
type StateValue = {
stateISO: string;
stateName: string;
@@ -721,6 +720,7 @@ const translations: TranslationDeepObject<typeof en> = {
'Non hai alcun dispositivo registrato per il riconoscimento facciale/impronta digitale o la verifica con passkey. Se ne registri uno, potrai revocare tale accesso qui.',
dismiss: 'Ho capito',
error: 'Richiesta non riuscita. Riprova più tardi.',
+ revoke: 'Revoca',
},
unsupportedDevice: {
unsupportedDevice: 'Dispositivo non supportato',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 52c19d6c..c1a6247a 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -175,7 +175,6 @@ import type {
ZipCodeExampleFormatParams,
} from './params';
import type {TranslationDeepObject} from './types';
-
type StateValue = {
stateISO: string;
stateName: string;
@@ -719,6 +718,7 @@ const translations: TranslationDeepObject<typeof en> = {
noDevices: '顔認証/指紋認証またはパスキー認証用に登録されているデバイスがありません。デバイスを登録すると、そのアクセスをここで取り消せるようになります。',
dismiss: '了解しました',
error: 'リクエストに失敗しました。後でもう一度お試しください。',
+ revoke: '取り消す',
},
unsupportedDevice: {
unsupportedDevice: '未対応のデバイス',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index c0be40bd..6bd712e8 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -175,7 +175,6 @@ import type {
ZipCodeExampleFormatParams,
} from './params';
import type {TranslationDeepObject} from './types';
-
type StateValue = {
stateISO: string;
stateName: string;
@@ -720,6 +719,7 @@ const translations: TranslationDeepObject<typeof en> = {
noDevices: 'Je hebt geen apparaten geregistreerd voor gezichts-/vingerafdruk- of passkey-verificatie. Als je er een registreert, kun je die toegang hier intrekken.',
dismiss: 'Begrepen',
error: 'Aanvraag mislukt. Probeer het later opnieuw.',
+ revoke: 'Intrekken',
},
unsupportedDevice: {
unsupportedDevice: 'Niet-ondersteund apparaat',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index ae74d432..5c159321 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -175,7 +175,6 @@ import type {
ZipCodeExampleFormatParams,
} from './params';
import type {TranslationDeepObject} from './types';
-
type StateValue = {
stateISO: string;
stateName: string;
@@ -721,6 +720,7 @@ const translations: TranslationDeepObject<typeof en> = {
'Nie masz zarejestrowanych żadnych urządzeń do weryfikacji twarzą/odciskiem palca ani kluczem dostępu. Jeśli jakieś zarejestrujesz, będziesz mógł/mogła cofnąć ten dostęp tutaj.',
dismiss: 'Rozumiem',
error: 'Żądanie nie powiodło się. Spróbuj ponownie później.',
+ revoke: 'Odwołaj',
},
unsupportedDevice: {
unsupportedDevice: 'Nieobsługiwane urządzenie',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 4404d137..3684443a 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -175,7 +175,6 @@ import type {
ZipCodeExampleFormatParams,
} from './params';
import type {TranslationDeepObject} from './types';
-
type StateValue = {
stateISO: string;
stateName: string;
@@ -719,6 +718,7 @@ const translations: TranslationDeepObject<typeof en> = {
noDevices: 'Você não tem nenhum dispositivo registrado para verificação por rosto/digital ou passkey. Se você registrar algum, poderá revogar esse acesso aqui.',
dismiss: 'Entendi',
error: 'Falha na solicitação. Tente novamente mais tarde.',
+ revoke: 'Revogar',
},
unsupportedDevice: {
unsupportedDevice: 'Dispositivo não compatível',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index eccc5d84..4bbf5067 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -175,7 +175,6 @@ import type {
ZipCodeExampleFormatParams,
} from './params';
import type {TranslationDeepObject} from './types';
-
type StateValue = {
stateISO: string;
stateName: string;
@@ -714,6 +713,7 @@ const translations: TranslationDeepObject<typeof en> = {
noDevices: '您尚未注册用于面部 / 指纹或通行密钥验证的任何设备。如果您注册了设备,之后可以在此撤销该访问权限。',
dismiss: '明白了',
error: '请求失败。请稍后重试。',
+ revoke: '撤销',
},
unsupportedDevice: {
unsupportedDevice: '不支持的设备',
Note You can apply these changes to your branch by copying the patch to your clipboard, then running |
|
🚧 @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! 🧪🧪
|
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb ChromeiOS: HybridAppiOS: mWeb SafariMacOS: Chrome / Safari |
|
🚧 @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.21-0 🚀
|
|
🚀 Deployed to production by https://github.com/mountiny in version: 9.3.21-4 🚀
|
Explanation of Change
We need to make sure the user sees the soft prompt in cases where both of the following are true:
Fixed Issues
$ #82605
PROPOSAL:
Tests
Notes:
Testnext toBiometrics"Case this PR solves for: Re-enroll two devices
Removebutton to revoke the user's biometrics from either device. Both devices should now display(Not registered)where they displayed(Registered)beforeCase: we have not regressed in the iOS reinstall case
Removebutton)Note that in this case, you will not be prompted for a magic code, and you will only be prompted to scan your face once. This is expected
Verify that no errors appear in the JS console
Offline tests
QA Steps
Same as tests
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand 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
Android: Native
re-enroll.works.android.mp4
iOS: Native
Base case: re-enroll when another device is enrolled
re-enroll.works.mp4
case: show soft prompt after reinstalling app
soft.prompt.after.reinstall.ios.mp4