Skip to content

Commit 3cd133f

Browse files
feat(a11y): inline error TwoFactorModal (#6448)
* fix: TOTP message always false * feat: inline errors TwoFactor modal * fix: a11y announcement on setData * fix: i18n
1 parent 3bbbe11 commit 3cd133f

File tree

25 files changed

+83
-13
lines changed

25 files changed

+83
-13
lines changed

app/containers/TwoFactor/index.tsx

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import React, { useEffect, useState } from 'react';
2-
import { InteractionManager, Text, View } from 'react-native';
2+
import { AccessibilityInfo, Text, View } from 'react-native';
33
import isEmpty from 'lodash/isEmpty';
44
import { sha256 } from 'js-sha256';
55
import Modal from 'react-native-modal';
66
import useDeepCompareEffect from 'use-deep-compare-effect';
7+
import { useForm } from 'react-hook-form';
8+
import * as yup from 'yup';
9+
import { yupResolver } from '@hookform/resolvers/yup';
710

8-
import { FormTextInput } from '../TextInput';
11+
import { ControlledFormTextInput } from '../TextInput';
912
import I18n from '../../i18n';
1013
import EventEmitter from '../../lib/methods/helpers/events';
1114
import { useTheme } from '../../theme';
@@ -59,13 +62,27 @@ const methods: IMethods = {
5962
};
6063

6164
const TwoFactor = React.memo(() => {
65+
const schema = yup.object().shape({
66+
code: yup.string().required(I18n.t('Code_required'))
67+
});
6268
const { colors } = useTheme();
6369
const { isMasterDetail } = useAppSelector(state => ({
6470
isMasterDetail: state.app.isMasterDetail as boolean
6571
}));
6672
const [visible, setVisible] = useState(false);
6773
const [data, setData] = useState<EventListenerMethod>({});
68-
const [code, setCode] = useState<string>('');
74+
const {
75+
control,
76+
setValue,
77+
getValues,
78+
formState: { errors },
79+
setError
80+
} = useForm({
81+
defaultValues: {
82+
code: ''
83+
},
84+
resolver: yupResolver(schema)
85+
});
6986

7087
const method = data.method ? methods[data.method] : null;
7188
const isEmail = data.method === 'email';
@@ -86,7 +103,7 @@ const TwoFactor = React.memo(() => {
86103

87104
useDeepCompareEffect(() => {
88105
if (!isEmpty(data)) {
89-
setCode('');
106+
setValue('code', '');
90107
setVisible(true);
91108
} else {
92109
setVisible(false);
@@ -95,6 +112,10 @@ const TwoFactor = React.memo(() => {
95112

96113
const showTwoFactor = (args: EventListenerMethod) => {
97114
setData(args);
115+
if (args.invalid) {
116+
setError('code', { message: I18n.t('Invalid_code'), type: 'validate' });
117+
AccessibilityInfo.announceForAccessibility(I18n.t('Invalid_code'));
118+
}
98119
};
99120

100121
useEffect(() => {
@@ -114,6 +135,7 @@ const TwoFactor = React.memo(() => {
114135
const onSubmit = () => {
115136
const { submit } = data;
116137
if (submit) {
138+
const { code } = getValues();
117139
if (data.method === 'password') {
118140
submit(sha256(code));
119141
} else {
@@ -140,22 +162,20 @@ const TwoFactor = React.memo(() => {
140162
]}>
141163
<Text style={[styles.title, { color }]}>{I18n.t(method?.title || 'Two_Factor_Authentication')}</Text>
142164
{method?.text ? <Text style={[styles.subtitle, { color }]}>{I18n.t(method.text)}</Text> : null}
143-
<FormTextInput
165+
<ControlledFormTextInput
166+
name='code'
167+
control={control}
168+
autoFocus
144169
returnKeyType='send'
145170
autoCapitalize='none'
146171
testID='two-factor-input'
147172
accessibilityLabel={I18n.t(
148173
data?.method === 'password' ? 'Label_Input_Two_Factor_Password' : 'Label_Input_Two_Factor_Code'
149174
)}
150-
value={code}
151-
inputRef={(e: any) => {
152-
InteractionManager.runAfterInteractions(() => e?.getNativeRef()?.focus());
153-
}}
154-
onChangeText={setCode}
155175
onSubmitEditing={onSubmit}
156176
keyboardType={method?.keyboardType}
157177
secureTextEntry={method?.secureTextEntry}
158-
error={data.invalid ? { error: 'totp-invalid', reason: I18n.t('Code_or_password_invalid') } : undefined}
178+
error={errors.code?.message}
159179
containerStyle={styles.containerInput}
160180
/>
161181

app/i18n/locales/ar.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"Click_to_join": "انقر للانضمام!",
9090
"Close": "إغلاق",
9191
"Code_or_password_invalid": "الرمز أو كلمة المرور خاطئة",
92+
"Code_required": "الكود مطلوب",
9293
"Collaborative": "تعاونية",
9394
"Confirm": "تأكيد",
9495
"Confirm_Password": "تأكيد كلمة المرور",
@@ -225,6 +226,7 @@
225226
"In_App_And_Desktop": "تطبيق داخلي وسطح المكتب",
226227
"In_App_and_Desktop_Alert_info": "يعرض شعاراً أعلى الشاشة عندما يكون التطبيق مفتوحًا، ويعرض إشعاراً على سطح المكتب",
227228
"Insert_Join_Code": "ضع رمز الانضمام",
229+
"Invalid_code": "رمز غير صالح",
228230
"Invalid_or_expired_invite_token": "رمز الدعوة غير صالح أو منتهي الصلاحية",
229231
"Invalid_server_version": "الخادم الذي تحاول الاتصال به يستخدم إصدارا لم يعد مدعوماً: {{currentVersion}}.\n\n النسخ المدعومة تبدأ من {{minVersion}}",
230232
"Invalid_URL": "عنوان URL غير صالح",

app/i18n/locales/bn-IN.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
"Close": "বন্ধ করুন",
139139
"Close_Chat": "চ্যাট বন্ধ করুন",
140140
"Code_or_password_invalid": "কোড বা পাসওয়ার্ড অবৈধ",
141+
"Code_required": "কোড প্রয়োজন",
141142
"Collaborative": "সহযোগী",
142143
"Condensed": "সংকোচিত",
143144
"conference_call": "কনফারেন্স কল",
@@ -342,6 +343,7 @@
342343
"Incoming_call_from": "হোস্ট হতে ইনকামিং কল",
343344
"insert_Avatar_URL": "এখানে চিত্র URL প্রবেশ করুন",
344345
"Insert_Join_Code": "যোগদান কোড প্রবেশ করুন",
346+
"Invalid_code": "অবৈধ কোড",
345347
"Invalid_or_expired_invite_token": "অকার্যকর বা মেয়াদ উত্তীর্ণ ইনভাইট টোকেন",
346348
"Invalid_server_version": "আপনি যাচাই করতে চেষ্টা করছেন তার একটি সংস্করণ ব্যবহার করছেন যা এখনও অ্যাপ দ্বারা সাপোর্ট করা হয়নি: {{currentVersion}}।\n\nআমরা সংস্করণ {{minVersion}} প্রয়োজন প্রয়োজন",
347349
"Invalid_URL": "অবৈধ URL",

app/i18n/locales/cs.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@
146146
"Close_Chat": "Zavřít chat",
147147
"Code_block": "Blok kódu",
148148
"Code_or_password_invalid": "Neplatný kód nebo heslo",
149+
"Code_required": "Potřebný kód",
149150
"Collaborative": "Spolupráce",
150151
"Community_edition_push_quota": "Komunitní push kvóta",
151152
"Condensed": "Zhuštěný",
@@ -365,6 +366,7 @@
365366
"Inline_code": "Vložený kód",
366367
"insert_Avatar_URL": "sem vložte adresu URL obrázku",
367368
"Insert_Join_Code": "Vložte připojovací kód",
369+
"Invalid_code": "Neplatný kód",
368370
"Invalid_Email": "Neplatný e-mail",
369371
"Invalid_or_expired_invite_token": "Neplatný nebo vypršela platnost tokenu pozvánky",
370372
"Invalid_server_version": "Pracovní prostor, který se pokoušíte připojit, používá verzi, která již není aplikací podporována: {{currentVersion}}.\n\nPožadujeme verzi {{minVersion}}",

app/i18n/locales/de.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
"Close": "Schließen",
134134
"Close_Chat": "Chat schließen",
135135
"Code_or_password_invalid": "Code oder Passwort sind falsch",
136+
"Code_required": "Code erforderlich",
136137
"Collaborative": "Kollaborativ",
137138
"Condensed": "Komprimiert",
138139
"Confirm": "Bestätigen",
@@ -335,6 +336,7 @@
335336
"Incoming_call_from": "Eingehender Anruf von",
336337
"insert_Avatar_URL": "Bild-URL hier einfügen",
337338
"Insert_Join_Code": "Beitrittscode eingeben",
339+
"Invalid_code": "Ungültiger Code",
338340
"Invalid_or_expired_invite_token": "Ungültiger oder abgelaufener Einladungscode",
339341
"Invalid_server_version": "Der Server, mit dem Sie sich verbinden möchten, verwendet eine Version, die von der App nicht mehr unterstützt wird: {{currentVersion}}.\n\nWir benötigen Version {{minVersion}}.",
340342
"Invalid_URL": "Ungültige URL",

app/i18n/locales/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
"Close_Chat": "Close chat",
149149
"Code_block": "Code block",
150150
"Code_or_password_invalid": "Code or password invalid",
151+
"Code_required": "Code required",
151152
"Collaborative": "Collaborative",
152153
"Community_edition_push_quota": "Community push quota",
153154
"Condensed": "Condensed",
@@ -386,6 +387,7 @@
386387
"Inline_code": "Inline code",
387388
"insert_Avatar_URL": "insert image URL here",
388389
"Insert_Join_Code": "Insert join code",
390+
"Invalid_code": "Invalid code",
389391
"Invalid_Email": "Invalid email",
390392
"Invalid_or_expired_invite_token": "Invalid or expired invite token",
391393
"Invalid_server_version": "The workspace you're trying to connect is using a version that's not supported by the app anymore: {{currentVersion}}.\n\nWe require version {{minVersion}}",

app/i18n/locales/es.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
"Choose_from_library": "Seleccionar desde galería",
7474
"Click_to_join": "¡Unirme!",
7575
"Close": "Cerrar",
76+
"Code_required": "Código requerido",
7677
"Collaborative": "Colaborativo",
7778
"Confirm": "Confirmar",
7879
"Confirm_Password": "confirmar Contraseña",
@@ -169,6 +170,7 @@
169170
"Hide_room": "Ocultar",
170171
"In_App_And_Desktop": "En la aplicación y en el escritorio",
171172
"In_App_and_Desktop_Alert_info": "Muestra un banner en la parte superior de la pantalla cuando la aplicación esté abierta y muestra una notificación en el escritorio",
173+
"Invalid_code": "Código inválido",
172174
"Invalid_server_version": "El servidor que intentas conectar está usando una versión que ya no está soportada por la aplicación : {{currentVersion}}. Se requiere una versión {{minVersion}}.",
173175
"Invalid_URL": "URL no válida",
174176
"Invalid_workspace_URL": "URL del espacio de trabajo no válida",

app/i18n/locales/fi.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
"Close": "Sulje",
124124
"Close_Chat": "Sulje keskustelu",
125125
"Code_or_password_invalid": "Koodi tai salasana virheellinen",
126+
"Code_required": "Koodi vaaditaan",
126127
"Collaborative": "Yhteistyö",
127128
"Condensed": "Tiivistetty",
128129
"Confirm": "Vahvista",
@@ -317,6 +318,7 @@
317318
"In_App_And_Desktop": "Sovelluksessa ja työpöydällä",
318319
"In_App_and_Desktop_Alert_info": "Näyttää bannerin näytön yläreunassa, kun sovellus on avoinna, ja näyttää ilmoituksen työpöydällä",
319320
"Insert_Join_Code": "Lisää liittymiskoodi",
321+
"Invalid_code": "Virheellinen koodi",
320322
"Invalid_or_expired_invite_token": "Virheellinen tai vanhentunut kutsutunnus",
321323
"Invalid_server_version": "Palvelin, johon yrität muodostaa yhteyttä, käyttää versiota, jota sovellus ei enää tue: {{currentVersion}}.\n\nEdellytämme versiota {{minVersion}}",
322324
"Invalid_URL": "Virheellinen URL-osoite.",

app/i18n/locales/fr.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
"Click_to_join": "Cliquez pour rejoindre !",
102102
"Close": "Fermer",
103103
"Code_or_password_invalid": "Code ou mot de passe invalide",
104+
"Code_required": "Code requis",
104105
"Collaborative": "Collaboratif",
105106
"Condensed": "Condensé",
106107
"Confirm": "Confirmer",
@@ -282,6 +283,7 @@
282283
"In_App_And_Desktop": "Dans l'application et sur le bureau",
283284
"In_App_and_Desktop_Alert_info": "Affiche une bannière en haut de l'écran lorsque l'application est ouverte et affiche une notification sur le bureau",
284285
"Insert_Join_Code": "Insérer le code d'adhésion",
286+
"Invalid_code": "Code invalide",
285287
"Invalid_or_expired_invite_token": "Jeton d'invitation non valide ou expiré",
286288
"Invalid_server_version": "Le serveur auquel vous essayez de vous connecter utilise une version qui n'est plus prise en charge par l'application : {{currentVersion}}.\n\nNous exigeons la version {{minVersion}}",
287289
"Invalid_URL": "URL invalide",

app/i18n/locales/hi-IN.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
"Close": "बंद करें",
139139
"Close_Chat": "चैट बंद करें",
140140
"Code_or_password_invalid": "कोड या पासवर्ड अमान्य है",
141+
"Code_required": "कोड आवश्यक है।",
141142
"Collaborative": "सहयोगी",
142143
"Condensed": "संक्षेपित",
143144
"conference_call": "कॉन्फ़्रेंस कॉल",
@@ -342,6 +343,7 @@
342343
"Incoming_call_from": "की ओर से आई कॉल",
343344
"insert_Avatar_URL": "यहां छवि URL डालें",
344345
"Insert_Join_Code": "सामिल होने का कोड डालें",
346+
"Invalid_code": "अमान्य कोड",
345347
"Invalid_or_expired_invite_token": "अमान्य या समाप्त होने वाला निमंत्रण टोकन",
346348
"Invalid_server_version": "यह कार्यस्थान जिससे आप कनेक्ट करने का प्रयास कर रहे हैं, वह ऐप द्वारा अब समर्थित नहीं है: {{currentVersion}}।\n\nहमें {{minVersion}} संस्करण की आवश्यकता है",
347349
"Invalid_URL": "अमान्य URL",

0 commit comments

Comments
 (0)