ordering-ui-react-native 0.15.93-release → 0.15.94-release
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/types/@fatnlazycat/react-native-recaptcha-v3/index.d.ts +1 -0
- package/themes/business/src/components/LoginForm/index.tsx +110 -74
- package/themes/kiosk/src/components/LoginForm/index.tsx +121 -10
- package/themes/kiosk/src/components/LoginForm/styles.tsx +5 -0
- package/themes/kiosk/src/types/index.d.ts +2 -0
- package/themes/original/src/components/LoginForm/index.tsx +70 -33
- package/themes/original/src/components/SignupForm/index.tsx +72 -34
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ordering-ui-react-native",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.94-release",
|
|
4
4
|
"description": "Reusable components made in react native",
|
|
5
5
|
"main": "src/index.tsx",
|
|
6
6
|
"author": "ordering.inc",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"lint": "eslint ."
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"@fatnlazycat/react-native-recaptcha-v3": "^1.0.3",
|
|
36
37
|
"@invertase/react-native-apple-authentication": "^2.1.5",
|
|
37
38
|
"@react-native-async-storage/async-storage": "^1.15.5",
|
|
38
39
|
"@react-native-clipboard/clipboard": "^1.8.4",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module '@fatnlazycat/react-native-recaptcha-v3'
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from 'react-native';
|
|
10
10
|
import { useForm, Controller } from 'react-hook-form';
|
|
11
11
|
import Recaptcha from 'react-native-recaptcha-that-works'
|
|
12
|
+
import ReCaptcha from '@fatnlazycat/react-native-recaptcha-v3'
|
|
12
13
|
import { TouchableOpacity } from 'react-native-gesture-handler';
|
|
13
14
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
|
14
15
|
import {
|
|
@@ -52,8 +53,8 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
52
53
|
allowedLevels,
|
|
53
54
|
useRootPoint,
|
|
54
55
|
notificationState,
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
handleReCaptcha,
|
|
57
|
+
enableReCaptcha
|
|
57
58
|
} = props;
|
|
58
59
|
|
|
59
60
|
const [ordering, { setOrdering }] = useApi();
|
|
@@ -67,7 +68,7 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
67
68
|
const inputRef = useRef<any>(null);
|
|
68
69
|
const inputMailRef = useRef<any>(null);
|
|
69
70
|
|
|
70
|
-
const [projectName, setProjectName] = useState({name: '', isFocued: false});
|
|
71
|
+
const [projectName, setProjectName] = useState({ name: '', isFocued: false });
|
|
71
72
|
const [passwordSee, setPasswordSee] = useState(false);
|
|
72
73
|
const [isLoadingVerifyModal, setIsLoadingVerifyModal] = useState(false);
|
|
73
74
|
const [isModalVisible, setIsModalVisible] = useState(false);
|
|
@@ -92,36 +93,50 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
92
93
|
const [formValues, setFormValues] = useState(null);
|
|
93
94
|
|
|
94
95
|
const [recaptchaConfig, setRecaptchaConfig] = useState<any>({})
|
|
95
|
-
|
|
96
|
+
const [recaptchaVerified, setRecaptchaVerified] = useState(false)
|
|
96
97
|
|
|
97
98
|
const recaptchaRef = useRef<any>({});
|
|
98
99
|
|
|
99
100
|
const handleOpenRecaptcha = () => {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
101
|
+
setRecaptchaVerified(false)
|
|
102
|
+
if (!recaptchaConfig?.siteKey) {
|
|
103
|
+
showToast(ToastType.Error, t('NO_RECAPTCHA_SITE_KEY', 'The config doesn\'t have recaptcha site key'));
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
if (!recaptchaConfig?.baseUrl) {
|
|
107
|
+
showToast(ToastType.Error, t('NO_RECAPTCHA_BASE_URL', 'The config doesn\'t have recaptcha base url'));
|
|
108
|
+
return
|
|
109
|
+
}
|
|
110
|
+
recaptchaRef.current.open()
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const onRecaptchaVerify = (token: any) => {
|
|
114
|
+
setRecaptchaVerified(true)
|
|
115
|
+
handleReCaptcha({ code: token, version: recaptchaConfig?.version })
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (configs && Object.keys(configs).length > 0 && enableReCaptcha) {
|
|
120
|
+
if (configs?.security_recaptcha_type?.value === 'v3' &&
|
|
121
|
+
configs?.security_recaptcha_score_v3?.value > 0 &&
|
|
122
|
+
configs?.security_recaptcha_site_key_v3?.value
|
|
123
|
+
) {
|
|
124
|
+
setRecaptchaConfig({
|
|
125
|
+
version: 'v3',
|
|
126
|
+
siteKey: configs?.security_recaptcha_site_key_v3?.value || null,
|
|
127
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
128
|
+
})
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
if (configs?.security_recaptcha_site_key?.value) {
|
|
132
|
+
setRecaptchaConfig({
|
|
133
|
+
version: 'v2',
|
|
134
|
+
siteKey: configs?.security_recaptcha_site_key?.value || null,
|
|
135
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}, [configs, enableReCaptcha])
|
|
125
140
|
|
|
126
141
|
useEffect(() => {
|
|
127
142
|
const projectInputInterval = setInterval(() => {
|
|
@@ -245,6 +260,17 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
245
260
|
|
|
246
261
|
useEffect(() => {
|
|
247
262
|
if (!formState?.loading && formState?.result?.error) {
|
|
263
|
+
if (formState.result?.result?.[0] === 'ERROR_AUTH_VERIFICATION_CODE') {
|
|
264
|
+
setRecaptchaVerified(false)
|
|
265
|
+
setSubmitted(false)
|
|
266
|
+
setRecaptchaConfig({
|
|
267
|
+
version: 'v2',
|
|
268
|
+
siteKey: configs?.security_recaptcha_site_key?.value || null,
|
|
269
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
270
|
+
})
|
|
271
|
+
showToast(ToastType.Info, t('TRY_AGAIN', 'Please try again'))
|
|
272
|
+
return
|
|
273
|
+
}
|
|
248
274
|
formState?.result?.result &&
|
|
249
275
|
showToast(
|
|
250
276
|
ToastType.Error,
|
|
@@ -252,17 +278,17 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
252
278
|
? getTraduction(formState.result?.result)
|
|
253
279
|
: loginTab === 'email' &&
|
|
254
280
|
typeof formState.result?.result !== 'string'
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
281
|
+
? getTraduction(formState.result?.result[0])
|
|
282
|
+
: loginTab === 'cellphone' &&
|
|
283
|
+
typeof formState.result?.result === 'string'
|
|
284
|
+
? getTraduction(formState.result?.result).replace(
|
|
285
|
+
t('USER', 'user').toLowerCase(),
|
|
286
|
+
t('PHONE_NUMER', 'Phone number'),
|
|
287
|
+
)
|
|
288
|
+
: getTraduction(formState.result?.result[0]).replace(
|
|
289
|
+
t('USER', 'user').toLowerCase(),
|
|
290
|
+
t('PHONE_NUMER', 'Phone number'),
|
|
291
|
+
),
|
|
266
292
|
);
|
|
267
293
|
setSubmitted(false)
|
|
268
294
|
}
|
|
@@ -516,7 +542,7 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
516
542
|
icon={theme.images.general.project}
|
|
517
543
|
iconColor={theme.colors.arrowColor}
|
|
518
544
|
onChange={(e: any) => {
|
|
519
|
-
setProjectName({name: e?.target?.value, isFocued: true})
|
|
545
|
+
setProjectName({ name: e?.target?.value, isFocued: true })
|
|
520
546
|
onChange(e?.target?.value);
|
|
521
547
|
setSubmitted(false);
|
|
522
548
|
}}
|
|
@@ -545,7 +571,7 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
545
571
|
icon={theme.images.logos.emailInputIcon}
|
|
546
572
|
iconColor={theme.colors.arrowColor}
|
|
547
573
|
onChange={(e: any) => {
|
|
548
|
-
setProjectName({...projectName, isFocued: false})
|
|
574
|
+
setProjectName({ ...projectName, isFocued: false })
|
|
549
575
|
handleChangeInputEmail(e, onChange);
|
|
550
576
|
}}
|
|
551
577
|
selectionColor={theme.colors.primary}
|
|
@@ -650,40 +676,50 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
650
676
|
</OText>
|
|
651
677
|
</Pressable>
|
|
652
678
|
)}
|
|
653
|
-
|
|
654
|
-
{enableReCaptcha && (
|
|
679
|
+
{(enableReCaptcha && recaptchaConfig?.version) && (
|
|
655
680
|
<>
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
{
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
681
|
+
{recaptchaConfig?.version === 'v3' ? (
|
|
682
|
+
<ReCaptcha
|
|
683
|
+
url={recaptchaConfig?.baseUrl}
|
|
684
|
+
siteKey={recaptchaConfig?.siteKey}
|
|
685
|
+
containerStyle={{ height: 40 }}
|
|
686
|
+
onExecute={onRecaptchaVerify}
|
|
687
|
+
reCaptchaType={1}
|
|
688
|
+
/>
|
|
689
|
+
) : (
|
|
690
|
+
<>
|
|
691
|
+
<TouchableOpacity
|
|
692
|
+
style={{ marginBottom: 15 }}
|
|
693
|
+
onPress={handleOpenRecaptcha}
|
|
694
|
+
>
|
|
695
|
+
<RecaptchaButton>
|
|
696
|
+
{recaptchaVerified ? (
|
|
697
|
+
<MaterialCommunityIcons
|
|
698
|
+
name="checkbox-marked"
|
|
699
|
+
size={26}
|
|
700
|
+
color={theme.colors.primary}
|
|
701
|
+
/>
|
|
702
|
+
) : (
|
|
703
|
+
<MaterialCommunityIcons
|
|
704
|
+
name="checkbox-blank-outline"
|
|
705
|
+
size={26}
|
|
706
|
+
color={theme.colors.mediumGray}
|
|
707
|
+
/>
|
|
708
|
+
)}
|
|
709
|
+
<OText size={14} mLeft={8}>{t('VERIFY_ReCAPTCHA', 'Verify reCAPTCHA')}</OText>
|
|
710
|
+
</RecaptchaButton>
|
|
711
|
+
</TouchableOpacity>
|
|
712
|
+
<Recaptcha
|
|
713
|
+
ref={recaptchaRef}
|
|
714
|
+
siteKey={recaptchaConfig?.siteKey}
|
|
715
|
+
baseUrl={recaptchaConfig?.baseUrl}
|
|
716
|
+
onVerify={onRecaptchaVerify}
|
|
717
|
+
onExpire={() => setRecaptchaVerified(false)}
|
|
718
|
+
/>
|
|
719
|
+
</>)
|
|
720
|
+
}
|
|
684
721
|
</>
|
|
685
|
-
|
|
686
|
-
|
|
722
|
+
)}
|
|
687
723
|
<OButton
|
|
688
724
|
onClick={handleLogin}
|
|
689
725
|
text={t('LOGIN', 'Login')}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
|
1
|
+
import React, { useEffect, useState, useRef } from 'react';
|
|
2
2
|
import { StyleSheet, View } from 'react-native';
|
|
3
3
|
import { useForm, Controller } from 'react-hook-form';
|
|
4
4
|
import { useTheme } from 'styled-components/native';
|
|
5
|
+
import { TouchableOpacity } from 'react-native-gesture-handler';
|
|
6
|
+
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
|
7
|
+
import Recaptcha from 'react-native-recaptcha-that-works'
|
|
8
|
+
import ReCaptcha from '@fatnlazycat/react-native-recaptcha-v3'
|
|
5
9
|
|
|
6
10
|
import {
|
|
7
11
|
LoginForm as LoginFormController,
|
|
12
|
+
useConfig,
|
|
8
13
|
useLanguage,
|
|
9
14
|
ToastType,
|
|
10
15
|
useToast,
|
|
@@ -13,7 +18,8 @@ import {
|
|
|
13
18
|
|
|
14
19
|
import {
|
|
15
20
|
WelcomeTextContainer,
|
|
16
|
-
LogoWrapper
|
|
21
|
+
LogoWrapper,
|
|
22
|
+
RecaptchaButton
|
|
17
23
|
} from './styles';
|
|
18
24
|
|
|
19
25
|
import { OText, OButton, OInput, OIcon } from '../shared';
|
|
@@ -26,14 +32,20 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
26
32
|
loginButtonText,
|
|
27
33
|
formState,
|
|
28
34
|
handleButtonLoginClick,
|
|
29
|
-
useRootPoint
|
|
35
|
+
useRootPoint,
|
|
36
|
+
handleReCaptcha,
|
|
37
|
+
enableReCaptcha
|
|
30
38
|
} = props;
|
|
31
39
|
|
|
32
40
|
const theme = useTheme()
|
|
41
|
+
const [{ configs }] = useConfig()
|
|
33
42
|
const [ordering, { setOrdering }] = useApi();
|
|
34
43
|
const [, { showToast }] = useToast();
|
|
35
44
|
const [, t] = useLanguage();
|
|
36
|
-
const
|
|
45
|
+
const [recaptchaConfig, setRecaptchaConfig] = useState<any>({})
|
|
46
|
+
const [recaptchaVerified, setRecaptchaVerified] = useState(false)
|
|
47
|
+
const recaptchaRef = useRef<any>({});
|
|
48
|
+
const { control, handleSubmit, formState: { errors } } = useForm();
|
|
37
49
|
const [orientationState] = useDeviceOrientation();
|
|
38
50
|
|
|
39
51
|
const [formsStateValues, setFormsStateValues] = useState<any>({ isSubmitted: false })
|
|
@@ -60,6 +72,25 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
60
72
|
onChange(value.toLowerCase().replace(/[&,()%";:ç?<>{}\\[\]\s]/g, ''));
|
|
61
73
|
};
|
|
62
74
|
|
|
75
|
+
const handleOpenRecaptcha = () => {
|
|
76
|
+
setRecaptchaVerified(false)
|
|
77
|
+
if (!recaptchaConfig?.siteKey) {
|
|
78
|
+
showToast(ToastType.Error, t('NO_RECAPTCHA_SITE_KEY', 'The config doesn\'t have recaptcha site key'));
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
if (!recaptchaConfig?.baseUrl) {
|
|
82
|
+
showToast(ToastType.Error, t('NO_RECAPTCHA_BASE_URL', 'The config doesn\'t have recaptcha base url'));
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
recaptchaRef.current.open()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const onRecaptchaVerify = (token: any) => {
|
|
90
|
+
setRecaptchaVerified(true)
|
|
91
|
+
handleReCaptcha && handleReCaptcha({ code: token, version: recaptchaConfig?.version })
|
|
92
|
+
}
|
|
93
|
+
|
|
63
94
|
const styles = StyleSheet.create({
|
|
64
95
|
logo: {
|
|
65
96
|
height: 80,
|
|
@@ -87,6 +118,20 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
87
118
|
|
|
88
119
|
useEffect(() => {
|
|
89
120
|
if (!formState.loading && formState.result?.error) {
|
|
121
|
+
if (formState.result?.result?.[0] === 'ERROR_AUTH_VERIFICATION_CODE') {
|
|
122
|
+
setRecaptchaVerified(false)
|
|
123
|
+
setRecaptchaConfig({
|
|
124
|
+
version: 'v2',
|
|
125
|
+
siteKey: configs?.security_recaptcha_site_key?.value || null,
|
|
126
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
127
|
+
})
|
|
128
|
+
showToast(ToastType.Info, t('TRY_AGAIN', 'Please try again'))
|
|
129
|
+
setFormsStateValues({
|
|
130
|
+
...formsStateValues,
|
|
131
|
+
isSubmitted: false,
|
|
132
|
+
})
|
|
133
|
+
return
|
|
134
|
+
}
|
|
90
135
|
formState.result?.result && showToast(
|
|
91
136
|
ToastType.Error,
|
|
92
137
|
typeof formState.result?.result === 'string'
|
|
@@ -122,9 +167,32 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
122
167
|
}
|
|
123
168
|
}, [errors]);
|
|
124
169
|
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
if (configs && Object.keys(configs).length > 0 && enableReCaptcha) {
|
|
172
|
+
if (configs?.security_recaptcha_type?.value === 'v3' &&
|
|
173
|
+
configs?.security_recaptcha_score_v3?.value > 0 &&
|
|
174
|
+
configs?.security_recaptcha_site_key_v3?.value
|
|
175
|
+
) {
|
|
176
|
+
setRecaptchaConfig({
|
|
177
|
+
version: 'v3',
|
|
178
|
+
siteKey: configs?.security_recaptcha_site_key_v3?.value || null,
|
|
179
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
180
|
+
})
|
|
181
|
+
return
|
|
182
|
+
}
|
|
183
|
+
if (configs?.security_recaptcha_site_key?.value) {
|
|
184
|
+
setRecaptchaConfig({
|
|
185
|
+
version: 'v2',
|
|
186
|
+
siteKey: configs?.security_recaptcha_site_key?.value || null,
|
|
187
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}, [configs, enableReCaptcha])
|
|
192
|
+
|
|
125
193
|
const logo = (
|
|
126
194
|
<LogoWrapper>
|
|
127
|
-
<OIcon src={theme.images.logos.logotype} style={styles.logo}/>
|
|
195
|
+
<OIcon src={theme.images.logos.logotype} style={styles.logo} />
|
|
128
196
|
</LogoWrapper>
|
|
129
197
|
);
|
|
130
198
|
|
|
@@ -144,7 +212,7 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
144
212
|
value={value}
|
|
145
213
|
autoCapitalize='none'
|
|
146
214
|
autoCorrect={false}
|
|
147
|
-
inputStyle={{textAlign: 'center'}}
|
|
215
|
+
inputStyle={{ textAlign: 'center' }}
|
|
148
216
|
onChange={(e: any) => {
|
|
149
217
|
onChange(e?.target?.value);
|
|
150
218
|
setFormsStateValues({
|
|
@@ -167,7 +235,7 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
167
235
|
autoCapitalize="none"
|
|
168
236
|
autoCorrect={false}
|
|
169
237
|
type="email-address"
|
|
170
|
-
inputStyle={{textAlign: 'center'}}
|
|
238
|
+
inputStyle={{ textAlign: 'center' }}
|
|
171
239
|
onChange={(e: any) => {
|
|
172
240
|
handleChangeInputEmail(e, onChange);
|
|
173
241
|
}}
|
|
@@ -199,7 +267,7 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
199
267
|
style={styles.inputStyle}
|
|
200
268
|
value={value}
|
|
201
269
|
onChange={(val: any) => onChange(val)}
|
|
202
|
-
inputStyle={{textAlign: 'center'}}
|
|
270
|
+
inputStyle={{ textAlign: 'center' }}
|
|
203
271
|
/>
|
|
204
272
|
)}
|
|
205
273
|
name="password"
|
|
@@ -211,7 +279,49 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
211
279
|
}}
|
|
212
280
|
defaultValue=""
|
|
213
281
|
/>
|
|
214
|
-
|
|
282
|
+
{(recaptchaConfig?.version) && (
|
|
283
|
+
<>
|
|
284
|
+
{recaptchaConfig?.version === 'v3' ? (
|
|
285
|
+
<ReCaptcha
|
|
286
|
+
url={recaptchaConfig?.baseUrl}
|
|
287
|
+
siteKey={recaptchaConfig?.siteKey}
|
|
288
|
+
containerStyle={{ height: 40 }}
|
|
289
|
+
onExecute={onRecaptchaVerify}
|
|
290
|
+
reCaptchaType={1}
|
|
291
|
+
/>
|
|
292
|
+
) : (
|
|
293
|
+
<>
|
|
294
|
+
<TouchableOpacity
|
|
295
|
+
onPress={handleOpenRecaptcha}
|
|
296
|
+
>
|
|
297
|
+
<RecaptchaButton>
|
|
298
|
+
{recaptchaVerified ? (
|
|
299
|
+
<MaterialCommunityIcons
|
|
300
|
+
name="checkbox-marked"
|
|
301
|
+
size={26}
|
|
302
|
+
color={theme.colors.primary}
|
|
303
|
+
/>
|
|
304
|
+
) : (
|
|
305
|
+
<MaterialCommunityIcons
|
|
306
|
+
name="checkbox-blank-outline"
|
|
307
|
+
size={26}
|
|
308
|
+
color={theme.colors.mediumGray}
|
|
309
|
+
/>
|
|
310
|
+
)}
|
|
311
|
+
<OText size={14} mLeft={8}>{t('VERIFY_ReCAPTCHA', 'Verify reCAPTCHA')}</OText>
|
|
312
|
+
</RecaptchaButton>
|
|
313
|
+
</TouchableOpacity>
|
|
314
|
+
<Recaptcha
|
|
315
|
+
ref={recaptchaRef}
|
|
316
|
+
siteKey={recaptchaConfig?.siteKey}
|
|
317
|
+
baseUrl={recaptchaConfig?.baseUrl}
|
|
318
|
+
onVerify={onRecaptchaVerify}
|
|
319
|
+
onExpire={() => setRecaptchaVerified(false)}
|
|
320
|
+
/>
|
|
321
|
+
</>)
|
|
322
|
+
}
|
|
323
|
+
</>
|
|
324
|
+
)}
|
|
215
325
|
<OButton
|
|
216
326
|
onClick={handleSubmit(onSubmit)}
|
|
217
327
|
text={loginButtonText}
|
|
@@ -280,7 +390,7 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
280
390
|
? 0 : 0,
|
|
281
391
|
}}
|
|
282
392
|
>
|
|
283
|
-
{
|
|
393
|
+
{welcome}
|
|
284
394
|
{orientationState?.orientation === LANDSCAPE && (
|
|
285
395
|
<View style={{
|
|
286
396
|
justifyContent: 'flex-end',
|
|
@@ -327,6 +437,7 @@ export const LoginForm = (props: any) => {
|
|
|
327
437
|
const loginProps = {
|
|
328
438
|
...props,
|
|
329
439
|
UIComponent: LoginFormUI,
|
|
440
|
+
isRecaptchaEnable: true
|
|
330
441
|
};
|
|
331
442
|
return <LoginFormController {...loginProps} />;
|
|
332
443
|
};
|
|
@@ -5,6 +5,7 @@ import { useForm, Controller } from 'react-hook-form';
|
|
|
5
5
|
import { PhoneInputNumber } from '../PhoneInputNumber';
|
|
6
6
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
|
7
7
|
import Recaptcha from 'react-native-recaptcha-that-works'
|
|
8
|
+
import ReCaptcha from '@fatnlazycat/react-native-recaptcha-v3'
|
|
8
9
|
|
|
9
10
|
import {
|
|
10
11
|
LoginForm as LoginFormController,
|
|
@@ -235,7 +236,7 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
235
236
|
|
|
236
237
|
const onRecaptchaVerify = (token: any) => {
|
|
237
238
|
setRecaptchaVerified(true)
|
|
238
|
-
handleReCaptcha(token)
|
|
239
|
+
handleReCaptcha({ code: token, version: recaptchaConfig?.version })
|
|
239
240
|
}
|
|
240
241
|
|
|
241
242
|
const handleChangeOtpType = (type: string) => {
|
|
@@ -272,15 +273,39 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
272
273
|
|
|
273
274
|
useEffect(() => {
|
|
274
275
|
if (configs && Object.keys(configs).length > 0 && enableReCaptcha) {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
276
|
+
if (configs?.security_recaptcha_type?.value === 'v3' &&
|
|
277
|
+
configs?.security_recaptcha_score_v3?.value > 0 &&
|
|
278
|
+
configs?.security_recaptcha_site_key_v3?.value
|
|
279
|
+
) {
|
|
280
|
+
setRecaptchaConfig({
|
|
281
|
+
version: 'v3',
|
|
282
|
+
siteKey: configs?.security_recaptcha_site_key_v3?.value || null,
|
|
283
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
284
|
+
})
|
|
285
|
+
return
|
|
286
|
+
}
|
|
287
|
+
if (configs?.security_recaptcha_site_key?.value) {
|
|
288
|
+
setRecaptchaConfig({
|
|
289
|
+
version: 'v2',
|
|
290
|
+
siteKey: configs?.security_recaptcha_site_key?.value || null,
|
|
291
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
292
|
+
})
|
|
293
|
+
}
|
|
279
294
|
}
|
|
280
295
|
}, [configs, enableReCaptcha])
|
|
281
296
|
|
|
282
297
|
useEffect(() => {
|
|
283
298
|
if (!formState.loading && formState.result?.error) {
|
|
299
|
+
if (formState.result?.result?.[0] === 'ERROR_AUTH_VERIFICATION_CODE') {
|
|
300
|
+
setRecaptchaVerified(false)
|
|
301
|
+
setRecaptchaConfig({
|
|
302
|
+
version: 'v2',
|
|
303
|
+
siteKey: configs?.security_recaptcha_site_key?.value || null,
|
|
304
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
305
|
+
})
|
|
306
|
+
showToast(ToastType.Info, t('TRY_AGAIN', 'Please try again'))
|
|
307
|
+
return
|
|
308
|
+
}
|
|
284
309
|
formState.result?.result &&
|
|
285
310
|
showToast(
|
|
286
311
|
ToastType.Error,
|
|
@@ -596,35 +621,47 @@ const LoginFormUI = (props: LoginParams) => {
|
|
|
596
621
|
</TouchableOpacity>
|
|
597
622
|
)}
|
|
598
623
|
|
|
599
|
-
{enableReCaptcha && (
|
|
624
|
+
{(enableReCaptcha && recaptchaConfig?.version) && (
|
|
600
625
|
<>
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
{
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
626
|
+
{recaptchaConfig?.version === 'v3' ? (
|
|
627
|
+
<ReCaptcha
|
|
628
|
+
url={recaptchaConfig?.baseUrl}
|
|
629
|
+
siteKey={recaptchaConfig?.siteKey}
|
|
630
|
+
containerStyle={{ height: 40 }}
|
|
631
|
+
onExecute={onRecaptchaVerify}
|
|
632
|
+
reCaptchaType={1}
|
|
633
|
+
/>
|
|
634
|
+
) : (
|
|
635
|
+
<>
|
|
636
|
+
<TouchableOpacity
|
|
637
|
+
onPress={handleOpenRecaptcha}
|
|
638
|
+
>
|
|
639
|
+
<RecaptchaButton>
|
|
640
|
+
{recaptchaVerified ? (
|
|
641
|
+
<MaterialCommunityIcons
|
|
642
|
+
name="checkbox-marked"
|
|
643
|
+
size={26}
|
|
644
|
+
color={theme.colors.primary}
|
|
645
|
+
/>
|
|
646
|
+
) : (
|
|
647
|
+
<MaterialCommunityIcons
|
|
648
|
+
name="checkbox-blank-outline"
|
|
649
|
+
size={26}
|
|
650
|
+
color={theme.colors.mediumGray}
|
|
651
|
+
/>
|
|
652
|
+
)}
|
|
653
|
+
<OText size={14} mLeft={8}>{t('VERIFY_ReCAPTCHA', 'Verify reCAPTCHA')}</OText>
|
|
654
|
+
</RecaptchaButton>
|
|
655
|
+
</TouchableOpacity>
|
|
656
|
+
<Recaptcha
|
|
657
|
+
ref={recaptchaRef}
|
|
658
|
+
siteKey={recaptchaConfig?.siteKey}
|
|
659
|
+
baseUrl={recaptchaConfig?.baseUrl}
|
|
660
|
+
onVerify={onRecaptchaVerify}
|
|
661
|
+
onExpire={() => setRecaptchaVerified(false)}
|
|
662
|
+
/>
|
|
663
|
+
</>)
|
|
664
|
+
}
|
|
628
665
|
</>
|
|
629
666
|
)}
|
|
630
667
|
<OButton
|
|
@@ -7,6 +7,7 @@ import CheckBox from '@react-native-community/checkbox';
|
|
|
7
7
|
import { PhoneInputNumber } from '../PhoneInputNumber';
|
|
8
8
|
import { FacebookLogin } from '../FacebookLogin';
|
|
9
9
|
import Recaptcha from 'react-native-recaptcha-that-works'
|
|
10
|
+
import ReCaptcha from '@fatnlazycat/react-native-recaptcha-v3'
|
|
10
11
|
|
|
11
12
|
import {
|
|
12
13
|
SignupForm as SignUpController,
|
|
@@ -347,20 +348,44 @@ const SignupFormUI = (props: SignupParams) => {
|
|
|
347
348
|
|
|
348
349
|
const onRecaptchaVerify = (token: any) => {
|
|
349
350
|
setRecaptchaVerified(true)
|
|
350
|
-
handleReCaptcha && handleReCaptcha(token)
|
|
351
|
+
handleReCaptcha && handleReCaptcha({ code: token, version: recaptchaConfig?.version })
|
|
351
352
|
}
|
|
352
353
|
|
|
353
354
|
useEffect(() => {
|
|
354
355
|
if (configs && Object.keys(configs).length > 0 && enableReCaptcha) {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
356
|
+
if (configs?.security_recaptcha_type?.value === 'v3' &&
|
|
357
|
+
configs?.security_recaptcha_score_v3?.value > 0 &&
|
|
358
|
+
configs?.security_recaptcha_site_key_v3?.value
|
|
359
|
+
) {
|
|
360
|
+
setRecaptchaConfig({
|
|
361
|
+
version: 'v3',
|
|
362
|
+
siteKey: configs?.security_recaptcha_site_key_v3?.value || null,
|
|
363
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
364
|
+
})
|
|
365
|
+
return
|
|
366
|
+
}
|
|
367
|
+
if (configs?.security_recaptcha_site_key?.value) {
|
|
368
|
+
setRecaptchaConfig({
|
|
369
|
+
version: 'v2',
|
|
370
|
+
siteKey: configs?.security_recaptcha_site_key?.value || null,
|
|
371
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
372
|
+
})
|
|
373
|
+
}
|
|
359
374
|
}
|
|
360
375
|
}, [configs, enableReCaptcha])
|
|
361
376
|
|
|
362
377
|
useEffect(() => {
|
|
363
378
|
if (!formState.loading && formState.result?.error) {
|
|
379
|
+
if (formState.result?.result?.[0] === 'ERROR_AUTH_VERIFICATION_CODE') {
|
|
380
|
+
setRecaptchaVerified(false)
|
|
381
|
+
setRecaptchaConfig({
|
|
382
|
+
version: 'v2',
|
|
383
|
+
siteKey: configs?.security_recaptcha_site_key?.value || null,
|
|
384
|
+
baseUrl: configs?.security_recaptcha_base_url?.value || null
|
|
385
|
+
})
|
|
386
|
+
showToast(ToastType.Info, t('TRY_AGAIN', 'Please try again'))
|
|
387
|
+
return
|
|
388
|
+
}
|
|
364
389
|
formState.result?.result &&
|
|
365
390
|
showToast(ToastType.Error, formState.result?.result[0]);
|
|
366
391
|
setIsLoadingVerifyModal(false);
|
|
@@ -626,36 +651,49 @@ const SignupFormUI = (props: SignupParams) => {
|
|
|
626
651
|
</View>
|
|
627
652
|
)}
|
|
628
653
|
|
|
629
|
-
{enableReCaptcha && (
|
|
654
|
+
{(enableReCaptcha && recaptchaConfig?.version) && (
|
|
630
655
|
<>
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
{
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
656
|
+
{recaptchaConfig?.version === 'v3' ? (
|
|
657
|
+
<ReCaptcha
|
|
658
|
+
url={recaptchaConfig?.baseUrl}
|
|
659
|
+
siteKey={recaptchaConfig?.siteKey}
|
|
660
|
+
containerStyle={{ height: 40 }}
|
|
661
|
+
onExecute={onRecaptchaVerify}
|
|
662
|
+
reCaptchaType={1}
|
|
663
|
+
/>
|
|
664
|
+
) : (
|
|
665
|
+
<>
|
|
666
|
+
<TouchableOpacity
|
|
667
|
+
onPress={handleOpenRecaptcha}
|
|
668
|
+
style={{ marginHorizontal: 4, marginBottom: 10 }}
|
|
669
|
+
>
|
|
670
|
+
<RecaptchaButton>
|
|
671
|
+
{recaptchaVerified ? (
|
|
672
|
+
<MaterialCommunityIcons
|
|
673
|
+
name="checkbox-marked"
|
|
674
|
+
size={23}
|
|
675
|
+
color={theme.colors.primary}
|
|
676
|
+
/>
|
|
677
|
+
) : (
|
|
678
|
+
<MaterialCommunityIcons
|
|
679
|
+
name="checkbox-blank-outline"
|
|
680
|
+
size={23}
|
|
681
|
+
color={theme.colors.disabled}
|
|
682
|
+
/>
|
|
683
|
+
)}
|
|
684
|
+
<OText size={14} mLeft={8}>{t('VERIFY_ReCAPTCHA', 'Verify reCAPTCHA')}</OText>
|
|
685
|
+
</RecaptchaButton>
|
|
686
|
+
</TouchableOpacity>
|
|
687
|
+
<Recaptcha
|
|
688
|
+
ref={recaptchaRef}
|
|
689
|
+
siteKey={recaptchaConfig?.siteKey}
|
|
690
|
+
baseUrl={recaptchaConfig?.baseUrl}
|
|
691
|
+
onVerify={onRecaptchaVerify}
|
|
692
|
+
onExpire={() => setRecaptchaVerified(false)}
|
|
693
|
+
/>
|
|
694
|
+
</>
|
|
695
|
+
)}
|
|
696
|
+
|
|
659
697
|
</>
|
|
660
698
|
)}
|
|
661
699
|
{(signUpTab === 'default') && (
|