From b32c7f5f8f1696c7c80244ebd340aaf7bce4fb28 Mon Sep 17 00:00:00 2001 From: Ryan Teguh Date: Thu, 7 May 2026 23:56:06 +0800 Subject: [PATCH 1/3] feat: Add caution message to magic code input on login --- src/languages/en.ts | 1 + .../ValidateCodeForm/BaseValidateCodeForm.tsx | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/languages/en.ts b/src/languages/en.ts index d1550f9a5098..c2986461c3bd 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2926,6 +2926,7 @@ const translations = { incorrectMagicCode: 'Incorrect or invalid magic code. Please try again or request a new code.', pleaseFillTwoFactorAuth: 'Please enter your two-factor authentication code', }, + avoidScamsMessage: 'Avoid scams. Do not share your code with anyone. Our team will never call, text, or email you for this code.', }, passwordForm: { pleaseFillOutAllFields: 'Please fill out all fields', diff --git a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.tsx b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.tsx index 59d97d642d6e..1055ef1efbb3 100755 --- a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.tsx +++ b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.tsx @@ -4,20 +4,24 @@ import {View} from 'react-native'; import Button from '@components/Button'; import SafariFormWrapper from '@components/Form/SafariFormWrapper'; import FormHelpMessage from '@components/FormHelpMessage'; +import Icon from '@components/Icon'; import type {MagicCodeInputHandle} from '@components/MagicCodeInput'; import MagicCodeInput from '@components/MagicCodeInput'; import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; +import RenderHTML from '@components/RenderHTML'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import ValidateCodeCountdown from '@components/ValidateCodeCountdown'; import type {ValidateCodeCountdownHandle} from '@components/ValidateCodeCountdown/types'; import type {WithToggleVisibilityViewProps} from '@components/withToggleVisibilityView'; import withToggleVisibilityView from '@components/withToggleVisibilityView'; +import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; import usePrevious from '@hooks/usePrevious'; import useStyleUtils from '@hooks/useStyleUtils'; +import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import AccountUtils from '@libs/AccountUtils'; import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus'; @@ -63,6 +67,8 @@ function BaseValidateCodeForm({autoComplete, isUsingRecoveryCode, setIsUsingReco const [needToClearError, setNeedToClearError] = useState(!!account?.errors); const [isCountdownRunning, setIsCountdownRunning] = useState(true); const StyleUtils = useStyleUtils(); + const theme = useTheme(); + const expensifyIcons = useMemoizedLazyExpensifyIcons(['Exclamation']); const prevRequiresTwoFactorAuth = usePrevious(account?.requiresTwoFactorAuth); const prevValidateCode = usePrevious(credentials?.validateCode); @@ -403,6 +409,18 @@ function BaseValidateCodeForm({autoComplete, isUsingRecoveryCode, setIsUsingReco )} + + + + + + + + )} From e0eac345003827cd8540cc5009eb621b4947002c Mon Sep 17 00:00:00 2001 From: Ryan Teguh Date: Fri, 8 May 2026 09:56:25 +0800 Subject: [PATCH 2/3] Add avoidScamsMessage translations --- src/languages/de.ts | 2 ++ src/languages/en.ts | 2 +- src/languages/es.ts | 2 ++ src/languages/fr.ts | 2 ++ src/languages/it.ts | 2 ++ src/languages/ja.ts | 2 ++ src/languages/nl.ts | 1 + src/languages/pl.ts | 1 + src/languages/pt-BR.ts | 2 ++ src/languages/zh-hans.ts | 1 + 10 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/languages/de.ts b/src/languages/de.ts index 4de93e2aae81..54dbd3560f60 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -2857,6 +2857,8 @@ ${amount} für ${merchant} – ${date}`, }, validateCodeForm: { magicCodeNotReceived: 'Keinen magischen Code erhalten?', + avoidScamsMessage: + 'Vermeide Betrug. Teile deinen Code mit niemandem. Unser Team wird dich niemals anrufen, dir SMS schreiben oder dir E-Mails zu diesem Code senden.', enterAuthenticatorCode: 'Bitte gib deinen Authentifizierungscode ein', enterRecoveryCode: 'Bitte gib deinen Wiederherstellungscode ein', requiredWhen2FAEnabled: 'Erforderlich, wenn 2FA aktiviert ist', diff --git a/src/languages/en.ts b/src/languages/en.ts index c2986461c3bd..cc9bee2bf055 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2914,6 +2914,7 @@ const translations = { }, validateCodeForm: { magicCodeNotReceived: "Didn't receive a magic code?", + avoidScamsMessage: 'Avoid scams. Do not share your code with anyone. Our team will never call, text, or email you for this code.', enterAuthenticatorCode: 'Please enter your authenticator code', enterRecoveryCode: 'Please enter your recovery code', requiredWhen2FAEnabled: 'Required when 2FA is enabled', @@ -2926,7 +2927,6 @@ const translations = { incorrectMagicCode: 'Incorrect or invalid magic code. Please try again or request a new code.', pleaseFillTwoFactorAuth: 'Please enter your two-factor authentication code', }, - avoidScamsMessage: 'Avoid scams. Do not share your code with anyone. Our team will never call, text, or email you for this code.', }, passwordForm: { pleaseFillOutAllFields: 'Please fill out all fields', diff --git a/src/languages/es.ts b/src/languages/es.ts index 4d165fcfc90c..d10637e82b22 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2750,6 +2750,8 @@ ${amount} para ${merchant} - ${date}`, }, validateCodeForm: { magicCodeNotReceived: '¿No recibiste un código mágico?', + avoidScamsMessage: + 'Evita las estafas. No compartas tu código con nadie. Nuestro equipo nunca te llamará, enviará mensajes de texto ni correos electrónicos para solicitarte este código.', enterAuthenticatorCode: 'Por favor, introduce el código de autenticador', enterRecoveryCode: 'Por favor, introduce tu código de recuperación', requiredWhen2FAEnabled: 'Obligatorio cuando A2F está habilitado', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 580833a8046c..442a4ea42352 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -2863,6 +2863,8 @@ ${amount} pour ${merchant} - ${date}`, }, validateCodeForm: { magicCodeNotReceived: "Vous n'avez pas reçu de code magique ?", + avoidScamsMessage: + 'Évitez les arnaques. Ne communiquez ce code à personne. Notre équipe ne vous contactera jamais par téléphone, SMS ou e-mail pour vous demander ce code.', enterAuthenticatorCode: 'Veuillez saisir votre code d’authentification', enterRecoveryCode: 'Veuillez saisir votre code de récupération', requiredWhen2FAEnabled: 'Obligatoire lorsque l’authentification à deux facteurs est activée', diff --git a/src/languages/it.ts b/src/languages/it.ts index 85412c276f1f..57c94a443c49 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -2853,6 +2853,8 @@ ${amount} per ${merchant} - ${date}`, }, validateCodeForm: { magicCodeNotReceived: 'Non hai ricevuto un codice magico?', + avoidScamsMessage: + 'Evita le truffe. Non rivelare il tuo codice a nessuno. Il nostro team non ti contatterà mai per telefono, SMS o e-mail per chiederti questo codice.', enterAuthenticatorCode: "Inserisci il tuo codice dell'autenticatore", enterRecoveryCode: 'Inserisci il tuo codice di recupero', requiredWhen2FAEnabled: 'Obbligatorio quando l’autenticazione a due fattori è abilitata', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 35666c340a22..59cec48a546f 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -2826,6 +2826,8 @@ ${date} の ${merchant} への ${amount}`, }, validateCodeForm: { magicCodeNotReceived: 'マジックコードを受け取っていませんか?', + avoidScamsMessage: + '詐欺に注意してください。このコードを誰にも共有しないでください。このコードについて、当社チームが電話、SMS、またはメールで連絡することはありません。', enterAuthenticatorCode: '認証コードを入力してください', enterRecoveryCode: 'リカバリーコードを入力してください', requiredWhen2FAEnabled: '2要素認証が有効な場合は必須', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 11864eee56d8..031228081aa7 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -2850,6 +2850,7 @@ ${amount} voor ${merchant} - ${date}`, }, validateCodeForm: { magicCodeNotReceived: 'Geen magische code ontvangen?', + avoidScamsMessage: 'Vermijd oplichting. Deel je code met niemand. Ons team zal je nooit bellen, sms’en of e-mailen om deze code te vragen.', enterAuthenticatorCode: 'Voer je authenticatiecode in', enterRecoveryCode: 'Voer uw herstelcode in', requiredWhen2FAEnabled: 'Vereist wanneer 2FA is ingeschakeld', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index fee79580a133..45eb98611230 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -2844,6 +2844,7 @@ ${amount} dla ${merchant} - ${date}`, }, validateCodeForm: { magicCodeNotReceived: 'Nie otrzymano magicznego kodu?', + avoidScamsMessage: 'Unikaj oszustw. Nie udostępniaj nikomu swojego kodu. Nasz zespół nigdy nie zadzwoni, nie wyśle SMS-a ani e-maila z prośbą o ten kod.', enterAuthenticatorCode: 'Wprowadź swój kod z aplikacji uwierzytelniającej', enterRecoveryCode: 'Wprowadź swój kod odzyskiwania', requiredWhen2FAEnabled: 'Wymagane, gdy włączone jest 2FA', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index d44b4ef42fa6..585e4ebfc901 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -2844,6 +2844,8 @@ ${amount} para ${merchant} - ${date}`, }, validateCodeForm: { magicCodeNotReceived: 'Não recebeu um código mágico?', + avoidScamsMessage: + 'Evite golpes. Não compartilhe seu código com ninguém. Nossa equipe nunca entrará em contato com você por telefone, mensagem de texto ou e-mail para pedir esse código.', enterAuthenticatorCode: 'Insira seu código do autenticador', enterRecoveryCode: 'Insira seu código de recuperação', requiredWhen2FAEnabled: 'Obrigatório quando a 2FA estiver ativada', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index d416e61161e1..4b11d1081fb0 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -2776,6 +2776,7 @@ ${amount},商户:${merchant} - 日期:${date}`, }, validateCodeForm: { magicCodeNotReceived: '没有收到验证码?', + avoidScamsMessage: '谨防诈骗。不要与任何人分享您的验证码。我们的团队绝不会致电、发短信或发送电子邮件向您索要此验证码。', enterAuthenticatorCode: '请输入您的认证器验证码', enterRecoveryCode: '请输入您的恢复代码', requiredWhen2FAEnabled: '启用双重验证时必填', From d3ab89a38e840706f42424c2b20b3264e2c3fd43 Mon Sep 17 00:00:00 2001 From: Ryan Teguh Date: Tue, 12 May 2026 08:24:24 +0800 Subject: [PATCH 3/3] Update avoidScamsMessage copy --- src/languages/de.ts | 2 +- src/languages/fr.ts | 2 +- src/languages/it.ts | 2 +- src/languages/ja.ts | 3 +-- src/languages/nl.ts | 2 +- src/languages/pt-BR.ts | 3 +-- src/languages/zh-hans.ts | 2 +- 7 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/languages/de.ts b/src/languages/de.ts index 84b7bbde197b..6c6ae99e7d4a 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -2863,7 +2863,7 @@ ${amount} für ${merchant} – ${date}`, validateCodeForm: { magicCodeNotReceived: 'Keinen magischen Code erhalten?', avoidScamsMessage: - 'Vermeide Betrug. Teile deinen Code mit niemandem. Unser Team wird dich niemals anrufen, dir SMS schreiben oder dir E-Mails zu diesem Code senden.', + 'Vermeiden Sie Betrug. Geben Sie Ihren Code nicht an andere weiter. Unser Team wird Sie niemals anrufen, per SMS kontaktieren oder Ihnen eine E-Mail senden, um diesen Code zu erfragen.', enterAuthenticatorCode: 'Bitte gib deinen Authentifizierungscode ein', enterRecoveryCode: 'Bitte gib deinen Wiederherstellungscode ein', requiredWhen2FAEnabled: 'Erforderlich, wenn 2FA aktiviert ist', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index c1229536e748..5f0d73bb6ac3 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -2869,7 +2869,7 @@ ${amount} pour ${merchant} - ${date}`, validateCodeForm: { magicCodeNotReceived: "Vous n'avez pas reçu de code magique ?", avoidScamsMessage: - 'Évitez les arnaques. Ne communiquez ce code à personne. Notre équipe ne vous contactera jamais par téléphone, SMS ou e-mail pour vous demander ce code.', + 'Évitez les arnaques. Ne partagez votre code avec personne. Notre équipe ne vous appellera, ne vous enverra jamais de SMS ni d’e-mail pour demander ce code.', enterAuthenticatorCode: 'Veuillez saisir votre code d’authentification', enterRecoveryCode: 'Veuillez saisir votre code de récupération', requiredWhen2FAEnabled: 'Obligatoire lorsque l’authentification à deux facteurs est activée', diff --git a/src/languages/it.ts b/src/languages/it.ts index ce1c02456677..c37c5d24efdb 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -2859,7 +2859,7 @@ ${amount} per ${merchant} - ${date}`, validateCodeForm: { magicCodeNotReceived: 'Non hai ricevuto un codice magico?', avoidScamsMessage: - 'Evita le truffe. Non rivelare il tuo codice a nessuno. Il nostro team non ti contatterà mai per telefono, SMS o e-mail per chiederti questo codice.', + 'Evita le truffe. Non condividere il tuo codice con nessuno. Il nostro team non ti chiamerà, invierà SMS o manderà email per chiederti questo codice.', enterAuthenticatorCode: "Inserisci il tuo codice dell'autenticatore", enterRecoveryCode: 'Inserisci il tuo codice di recupero', requiredWhen2FAEnabled: 'Obbligatorio quando l’autenticazione a due fattori è abilitata', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 3842b2cd1117..58d3dbd62f74 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -2831,8 +2831,7 @@ ${date} の ${merchant} への ${amount}`, }, validateCodeForm: { magicCodeNotReceived: 'マジックコードを受け取っていませんか?', - avoidScamsMessage: - '詐欺に注意してください。このコードを誰にも共有しないでください。このコードについて、当社チームが電話、SMS、またはメールで連絡することはありません。', + avoidScamsMessage: '詐欺に注意してください。コードを他人と共有しないでください。 当社スタッフがこのコードを電話・SMS・メールでお尋ねすることは決してありません。', enterAuthenticatorCode: '認証コードを入力してください', enterRecoveryCode: 'リカバリーコードを入力してください', requiredWhen2FAEnabled: '2要素認証が有効な場合は必須', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index d04eb62ade4b..9ac3d8eef15a 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -2855,7 +2855,7 @@ ${amount} voor ${merchant} - ${date}`, }, validateCodeForm: { magicCodeNotReceived: 'Geen magische code ontvangen?', - avoidScamsMessage: 'Vermijd oplichting. Deel je code met niemand. Ons team zal je nooit bellen, sms’en of e-mailen om deze code te vragen.', + avoidScamsMessage: 'Voorkom oplichting. Deel je code met niemand. Ons team zal je nooit bellen, sms’en of e-mailen om deze code te vragen.', enterAuthenticatorCode: 'Voer je authenticatiecode in', enterRecoveryCode: 'Voer uw herstelcode in', requiredWhen2FAEnabled: 'Vereist wanneer 2FA is ingeschakeld', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 00dc2d54ceda..c6d6bc5b44e9 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -2849,8 +2849,7 @@ ${amount} para ${merchant} - ${date}`, }, validateCodeForm: { magicCodeNotReceived: 'Não recebeu um código mágico?', - avoidScamsMessage: - 'Evite golpes. Não compartilhe seu código com ninguém. Nossa equipe nunca entrará em contato com você por telefone, mensagem de texto ou e-mail para pedir esse código.', + avoidScamsMessage: 'Evite golpes. Não compartilhe seu código com ninguém. Nossa equipe nunca ligará, enviará SMS ou e-mail para pedir esse código.', enterAuthenticatorCode: 'Insira seu código do autenticador', enterRecoveryCode: 'Insira seu código de recuperação', requiredWhen2FAEnabled: 'Obrigatório quando a 2FA estiver ativada', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index eed3b8625b62..c19d7758795b 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -2781,7 +2781,7 @@ ${amount},商户:${merchant} - 日期:${date}`, }, validateCodeForm: { magicCodeNotReceived: '没有收到验证码?', - avoidScamsMessage: '谨防诈骗。不要与任何人分享您的验证码。我们的团队绝不会致电、发短信或发送电子邮件向您索要此验证码。', + avoidScamsMessage: '谨防诈骗。不要与任何人分享您的验证码。 我们的团队绝不会打电话、发短信或发送电子邮件向您索取此验证码。', enterAuthenticatorCode: '请输入您的认证器验证码', enterRecoveryCode: '请输入您的恢复代码', requiredWhen2FAEnabled: '启用双重验证时必填',