1+
2+ //
3+ // ForgotPasswordScreen.js
4+ // CosyncJWT
5+ //
6+ // Licensed to the Apache Software Foundation (ASF) under one
7+ // or more contributor license agreements. See the NOTICE file
8+ // distributed with this work for additional information
9+ // regarding copyright ownership. The ASF licenses this file
10+ // to you under the Apache License, Version 2.0 (the
11+ // "License"); you may not use this file except in compliance
12+ // with the License. You may obtain a copy of the License at
13+ //
14+ // http://www.fapache.org/licenses/LICENSE-2.0
15+ //
16+ // Unless required by applicable law or agreed to in writing,
17+ // software distributed under the License is distributed on an
18+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19+ // KIND, either express or implied. See the License for the
20+ // specific language governing permissions and limitations
21+ // under the License.
22+ //
23+ // Created by Tola Voeung.
24+ // Copyright © 2022 cosync. All rights reserved.
25+ //
26+
27+ import React , { useEffect , useState , useRef } from 'react' ;
28+ import {
29+ StyleSheet ,
30+ TextInput ,
31+ View ,
32+ Text ,
33+ ScrollView ,
34+ Image ,
35+ Keyboard ,
36+ TouchableOpacity ,
37+ KeyboardAvoidingView ,
38+ } from 'react-native' ;
39+ import Loader from '../components/Loader' ;
40+ import { AuthContext } from '../context/AuthContext' ;
41+
42+ const ForgotPasswordScreen = props => {
43+
44+ let [ userEmail , setUserEmail ] = useState ( '' ) ;
45+ let [ verifyCode , setVerifyCode ] = useState ( false ) ;
46+ let [ loading , setLoading ] = useState ( false ) ;
47+ let [ errortext , setErrortext ] = useState ( '' ) ;
48+ let [ infotext , setInfotext ] = useState ( '' ) ;
49+ let [ resetCode , setResetCode ] = useState ( '' ) ;
50+ let [ userPassword , setUserPassword ] = useState ( '' ) ;
51+
52+ const ref_input_pwd = useRef ( ) ;
53+ const ref_input_code = useRef ( ) ;
54+ const { getApplication, appData, cosyncJWT } = useContext ( AuthContext )
55+
56+ useEffect ( ( ) => {
57+ getApplication ( ) ;
58+ } , [ ] ) ;
59+
60+
61+ const validateEmail = ( text ) => {
62+
63+ let reg = / ^ \w + ( [ \. - ] ? \w + ) * @ \w + ( [ \. - ] ? \w + ) * ( \. \w { 2 , 3 } ) + $ / ;
64+ if ( reg . test ( text ) === false ) return false ;
65+ else return true ;
66+ }
67+
68+
69+ const handleResetPassword = ( ) => {
70+ setErrortext ( '' ) ;
71+ if ( ! userEmail ) {
72+ alert ( 'Please fill Email' ) ;
73+ return ;
74+ }
75+ if ( ! validateEmail ( userEmail ) ) {
76+ alert ( 'Please fill a valid email' ) ;
77+ return ;
78+ }
79+
80+ if ( verifyCode ) {
81+ handleSubmitVerifyCodePress ( )
82+ }
83+ else {
84+
85+ setLoading ( true ) ;
86+ cosyncJWT . password . forgotPassword ( userEmail ) . then ( result => {
87+
88+ setLoading ( false ) ;
89+ console . log ( 'CosyncJWT forgotPassword result ' , result ) ;
90+
91+ if ( result ) {
92+ setInfotext ( `Please check your email for reset password ${ appData . signupFlow } .` ) ;
93+
94+ if ( appData . signupFlow == 'code' ) setVerifyCode ( true ) ;
95+ }
96+ } ) . catch ( err => {
97+ setLoading ( false ) ;
98+ console . log ( 'CosyncJWT forgotPassword err ' , err ) ;
99+ setErrortext ( err . message ) ;
100+ } )
101+ }
102+ } ;
103+
104+
105+
106+ const handleSubmitVerifyCodePress = ( ) => {
107+
108+ if ( ! userEmail ) {
109+ alert ( 'Please fill Email' ) ;
110+ return ;
111+ }
112+ if ( ! validateEmail ( userEmail ) ) {
113+ alert ( 'Please fill a valid email' ) ;
114+ return ;
115+ }
116+
117+
118+ if ( ! userPassword ) {
119+ alert ( 'Please fill Password' ) ;
120+ return ;
121+ }
122+
123+
124+ if ( ! resetCode ) {
125+ alert ( 'Please fill code' ) ;
126+ return ;
127+ }
128+
129+ let validate = cosyncJWT . password . validatePassword ( userPassword ) ;
130+ if ( ! validate ) {
131+ let message = `
132+ Error: Invalid Password Rules:\nMinimum password length : ${ appData . passwordMinLength }
133+ Minimun upper case : ${ appData . passwordMinUpper }
134+ Minimum lower case : ${ appData . passwordMinLower }
135+ Minimum digit charactor : ${ appData . passwordMinDigit }
136+ Minimum special charactor: ${ appData . passwordMinSpecial }
137+ ` ;
138+ setErrortext ( message ) ;
139+
140+ }
141+ else {
142+
143+ setLoading ( true ) ;
144+
145+ cosyncJWT . password . resetPassword ( userEmail , userPassword , resetCode ) . then ( result => {
146+ setLoading ( false ) ;
147+ console . log ( 'resetPassword ' , result ) ;
148+
149+ if ( result === true ) {
150+ alert ( 'Please login with your new password' ) ;
151+ props . navigation . navigate ( 'LoginScreen' ) ;
152+ }
153+ else {
154+
155+ setErrortext ( `Error: ${ result . message } ` ) ;
156+ }
157+ } ) . catch ( err => {
158+
159+ setLoading ( false ) ;
160+ setErrortext ( `Error: ${ err . message } ` ) ;
161+ } )
162+ }
163+ }
164+
165+
166+
167+ return (
168+ < View style = { styles . mainBody } >
169+ < Loader loading = { loading } />
170+
171+ < ScrollView keyboardShouldPersistTaps = "handled" >
172+
173+ < View style = { { marginTop : 100 } } >
174+ < KeyboardAvoidingView enabled >
175+ < View style = { { alignItems : 'center' } } >
176+ < Image
177+ source = { require ( '../assets/cosynclogo.png' ) }
178+ style = { {
179+ height : 200 ,
180+ resizeMode : 'contain' ,
181+ margin : 30 ,
182+ } }
183+ />
184+ </ View >
185+ < View style = { styles . SectionStyle } >
186+ < TextInput
187+ style = { styles . inputStyle }
188+ onChangeText = { UserEmail => setUserEmail ( UserEmail ) }
189+ placeholder = "Enter Email"
190+ autoCapitalize = "none"
191+ keyboardType = "email-address"
192+ returnKeyType = "next"
193+ autoComplete = { 'off' }
194+ blurOnSubmit = { false }
195+
196+ />
197+ </ View >
198+
199+
200+ { infotext != '' ? (
201+ < Text style = { styles . registerTextStyle } > { infotext } </ Text >
202+ ) : null }
203+
204+
205+ { verifyCode ?< View >
206+
207+ < View style = { styles . SectionStyle } >
208+ < TextInput
209+ style = { styles . inputStyle }
210+ onChangeText = { value => setUserPassword ( value ) }
211+ placeholder = "Enter new password"
212+ blurOnSubmit = { false }
213+ secureTextEntry = { true }
214+ textContentType = { 'none' }
215+ autoComplete = { 'off' }
216+ ref = { ref_input_pwd }
217+ onSubmitEditing = { ( ) => ref_input_code . current . focus ( ) }
218+ />
219+ </ View >
220+
221+ < View style = { styles . SectionStyle } >
222+ < TextInput
223+ style = { styles . inputStyle }
224+ onChangeText = { value => setResetCode ( value ) }
225+ placeholder = "Enter reset code"
226+ keyboardType = "numeric"
227+ returnKeyType = "go"
228+ blurOnSubmit = { false }
229+ textContentType = { 'none' }
230+ autoComplete = { 'off' }
231+ ref = { ref_input_code }
232+ onSubmitEditing = { ( ) => Keyboard . dismiss , handleSubmitVerifyCodePress }
233+ />
234+
235+ </ View >
236+ </ View > : null }
237+
238+ { errortext != '' ? (
239+ < Text style = { styles . errorTextStyle } > { errortext } </ Text >
240+ ) : null }
241+
242+
243+ < TouchableOpacity
244+ style = { styles . buttonStyle }
245+ activeOpacity = { 0.5 }
246+ onPress = { handleResetPassword } >
247+ < Text style = { styles . buttonTextStyle } > SUBMIT</ Text >
248+ </ TouchableOpacity >
249+
250+ </ KeyboardAvoidingView >
251+ </ View >
252+ </ ScrollView >
253+ </ View >
254+ ) ;
255+ } ;
256+ export default ForgotPasswordScreen ;
257+
258+ const styles = StyleSheet . create ( {
259+ mainBody : {
260+ flex : 1 ,
261+ justifyContent : 'center' ,
262+ backgroundColor : '#fff' ,
263+ } ,
264+ SectionStyle : {
265+ flexDirection : 'row' ,
266+ height : 40 ,
267+ marginTop : 20 ,
268+ marginLeft : 35 ,
269+ marginRight : 35 ,
270+ margin : 10 ,
271+ } ,
272+ buttonStyle : {
273+ backgroundColor : '#4638ab' ,
274+ borderWidth : 0 ,
275+ color : '#FFFFFF' ,
276+ borderColor : '#7DE24E' ,
277+ height : 40 ,
278+ alignItems : 'center' ,
279+ borderRadius : 30 ,
280+ marginLeft : 35 ,
281+ marginRight : 35 ,
282+ marginTop : 20 ,
283+ marginBottom : 20 ,
284+ } ,
285+ buttonTextStyle : {
286+ color : 'white' ,
287+ paddingVertical : 10 ,
288+ fontSize : 16 ,
289+ } ,
290+ inputStyle : {
291+ flex : 1 ,
292+ color : '#4638ab' ,
293+ paddingLeft : 15 ,
294+ paddingRight : 15 ,
295+ borderWidth : 1 ,
296+ borderRadius : 30 ,
297+ borderColor : '#4638ab' ,
298+ } ,
299+ registerTextStyle : {
300+ color : '#4638ab' ,
301+ textAlign : 'center' ,
302+ fontWeight : 'bold' ,
303+ fontSize : 14 ,
304+ } ,
305+ errorTextStyle : {
306+ color : 'red' ,
307+ textAlign : 'center' ,
308+ fontSize : 14 ,
309+ } ,
310+ } ) ;
0 commit comments