@chem-po/firebase-native 0.0.38 → 0.0.40

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.
Files changed (39) hide show
  1. package/lib/commonjs/adapter/auth.js +10 -3
  2. package/lib/commonjs/adapter/auth.js.map +1 -1
  3. package/lib/commonjs/components/FirebaseSignIn.js +20 -14
  4. package/lib/commonjs/components/FirebaseSignIn.js.map +1 -1
  5. package/lib/commonjs/components/PhoneVerify.js +45 -33
  6. package/lib/commonjs/components/PhoneVerify.js.map +1 -1
  7. package/lib/commonjs/components/TwoFactorAuthModal.js +72 -15
  8. package/lib/commonjs/components/TwoFactorAuthModal.js.map +1 -1
  9. package/lib/commonjs/hooks/usePhoneVerify.js +13 -5
  10. package/lib/commonjs/hooks/usePhoneVerify.js.map +1 -1
  11. package/lib/commonjs/utils/validation.js +4 -0
  12. package/lib/commonjs/utils/validation.js.map +1 -1
  13. package/lib/module/adapter/auth.js +10 -3
  14. package/lib/module/adapter/auth.js.map +1 -1
  15. package/lib/module/components/FirebaseSignIn.js +21 -15
  16. package/lib/module/components/FirebaseSignIn.js.map +1 -1
  17. package/lib/module/components/PhoneVerify.js +47 -35
  18. package/lib/module/components/PhoneVerify.js.map +1 -1
  19. package/lib/module/components/TwoFactorAuthModal.js +71 -15
  20. package/lib/module/components/TwoFactorAuthModal.js.map +1 -1
  21. package/lib/module/hooks/usePhoneVerify.js +13 -5
  22. package/lib/module/hooks/usePhoneVerify.js.map +1 -1
  23. package/lib/module/utils/validation.js +4 -0
  24. package/lib/module/utils/validation.js.map +1 -1
  25. package/lib/typescript/adapter/auth.d.ts.map +1 -1
  26. package/lib/typescript/components/FirebaseSignIn.d.ts.map +1 -1
  27. package/lib/typescript/components/PhoneVerify.d.ts.map +1 -1
  28. package/lib/typescript/components/TwoFactorAuthModal.d.ts +1 -0
  29. package/lib/typescript/components/TwoFactorAuthModal.d.ts.map +1 -1
  30. package/lib/typescript/hooks/usePhoneVerify.d.ts +3 -1
  31. package/lib/typescript/hooks/usePhoneVerify.d.ts.map +1 -1
  32. package/lib/typescript/utils/validation.d.ts.map +1 -1
  33. package/package.json +4 -4
  34. package/src/adapter/auth.ts +98 -83
  35. package/src/components/FirebaseSignIn.tsx +21 -14
  36. package/src/components/PhoneVerify.tsx +46 -33
  37. package/src/components/TwoFactorAuthModal.tsx +87 -23
  38. package/src/hooks/usePhoneVerify.ts +15 -4
  39. package/src/utils/validation.ts +7 -0
@@ -1,6 +1,8 @@
1
1
  import { EnrollmentFactor, PhoneEnrollmentFactor } from '@chem-po/core'
2
- import { useAuth, useBackgroundColor } from '@chem-po/react'
2
+ import { useAuth, useBackgroundColor, useBorderColor, useIconColor } from '@chem-po/react'
3
3
  import { Txt } from '@chem-po/react-native'
4
+ import { useFont } from '@chem-po/react-native/src/hooks/useFont'
5
+ import { Ionicons } from '@expo/vector-icons'
4
6
  import React, { useState } from 'react'
5
7
  import { ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native'
6
8
  import { Modal, Portal } from 'react-native-paper'
@@ -8,6 +10,46 @@ import { useBackend } from '../hooks/backend'
8
10
  import { AuthenticatorVerify } from './AuthenticatorVerify'
9
11
  import { PhoneVerify } from './PhoneVerify'
10
12
 
13
+ const FactorView = ({
14
+ factor,
15
+ buttonBackgroundColor,
16
+ iconColor,
17
+ borderColor,
18
+ onPress,
19
+ }: {
20
+ factor: EnrollmentFactor
21
+ buttonBackgroundColor: string
22
+ iconColor: string
23
+ borderColor: string
24
+ onPress: () => void
25
+ }) => {
26
+ return (
27
+ <TouchableOpacity
28
+ style={[
29
+ styles.factorButton,
30
+ {
31
+ backgroundColor: buttonBackgroundColor,
32
+ borderColor,
33
+ },
34
+ ]}
35
+ onPress={onPress}
36
+ >
37
+ <View style={styles.factorContent}>
38
+ <Ionicons
39
+ name={factor.type === 'phone' ? 'phone-portrait' : 'qr-code'}
40
+ size={20}
41
+ color={iconColor}
42
+ />
43
+ <Txt style={styles.factorHeaderText}>
44
+ {factor.type === 'phone' ? `Phone: ${factor.phoneNumber}` : 'Authenticator App'}
45
+ </Txt>
46
+ {factor.displayName ? (
47
+ <Txt style={styles.factorDetailsText}>{factor.displayName}</Txt>
48
+ ) : null}
49
+ </View>
50
+ </TouchableOpacity>
51
+ )
52
+ }
11
53
 
12
54
  const TwoFactorSelect = ({
13
55
  factors,
@@ -17,30 +59,22 @@ const TwoFactorSelect = ({
17
59
  onSelect: (factor: EnrollmentFactor) => void
18
60
  }) => {
19
61
  const buttonBackgroundColor = useBackgroundColor(100)
62
+ const borderColor = useBorderColor()
63
+ const iconColor = useIconColor()
64
+ const textFont = useFont('body', 'md')
20
65
  return (
21
66
  <View style={styles.selectContainer}>
22
- <Txt style={styles.selectTitle}>Select an option to verify with:</Txt>
67
+ <Txt style={[styles.selectTitle, textFont]}>Select an option to verify with:</Txt>
23
68
  <View style={styles.factorsList}>
24
69
  {factors.map((factor) => (
25
- <TouchableOpacity
26
- key={factor.uid}
27
- style={[
28
- styles.factorButton,
29
- {
30
- backgroundColor: buttonBackgroundColor,
31
- },
32
- ]}
70
+ <FactorView
71
+ key={`${factor.type}-${factor.enrollmentTime}`}
72
+ factor={factor}
73
+ buttonBackgroundColor={buttonBackgroundColor}
33
74
  onPress={() => onSelect(factor)}
34
- >
35
- <Txt style={styles.factorHeaderText}>
36
- {factor.type === 'phone' ? `Phone: ${factor.phoneNumber}` : 'Authenticator App'}
37
- </Txt>
38
- {
39
- factor.displayName ? (
40
- <Txt style={styles.factorDetailsText}>{factor.displayName}</Txt>
41
- ) : null
42
- }
43
- </TouchableOpacity>
75
+ iconColor={iconColor}
76
+ borderColor={borderColor}
77
+ />
44
78
  ))}
45
79
  </View>
46
80
  </View>
@@ -83,7 +117,9 @@ export const TwoFactorAuthModal = () => {
83
117
  <Portal>
84
118
  <Modal
85
119
  visible={true}
86
- onDismiss={() => { auth.logout() }}
120
+ onDismiss={() => {
121
+ auth.logout()
122
+ }}
87
123
  style={styles.modal}
88
124
  >
89
125
  <View style={[styles.modalContent, { backgroundColor }]}>
@@ -96,6 +132,28 @@ export const TwoFactorAuthModal = () => {
96
132
  )
97
133
  }
98
134
 
135
+ const testFactor: EnrollmentFactor = {
136
+ uid: 'test',
137
+ type: 'phone',
138
+ phoneNumber: '1234567890',
139
+ displayName: 'Test Phone',
140
+ enrollmentTime: '2021-01-01',
141
+ }
142
+ export const TestTwoFactorVerifyModal = () => {
143
+ const backgroundColor = useBackgroundColor(150)
144
+ return (
145
+ <Portal>
146
+ <Modal visible={true} onDismiss={() => {}} style={styles.modal}>
147
+ <View style={[styles.modalContent, { backgroundColor }]}>
148
+ <ScrollView contentContainerStyle={styles.scrollContent}>
149
+ <TwoFactorVerify factorInfo={testFactor} />
150
+ </ScrollView>
151
+ </View>
152
+ </Modal>
153
+ </Portal>
154
+ )
155
+ }
156
+
99
157
  const styles = StyleSheet.create({
100
158
  modal: {
101
159
  margin: 0,
@@ -113,18 +171,24 @@ const styles = StyleSheet.create({
113
171
  },
114
172
  selectTitle: {
115
173
  fontSize: 16,
116
- marginBottom: 16,
174
+ marginBottom: 8,
175
+ paddingHorizontal: 4,
117
176
  },
118
177
  factorsList: {
119
178
  gap: 8,
120
179
  },
180
+ factorContent: {
181
+ flexDirection: 'row',
182
+ alignItems: 'center',
183
+ gap: 8,
184
+ },
121
185
  factorButton: {
122
186
  padding: 16,
123
187
  borderRadius: 8,
124
188
  borderWidth: 1,
125
189
  },
126
190
  factorHeaderText: {
127
- fontSize: 14,
191
+ fontSize: 16,
128
192
  fontWeight: 'bold',
129
193
  opacity: 0.8,
130
194
  },
@@ -5,6 +5,7 @@ import { useBackend } from './backend'
5
5
 
6
6
  export const usePhoneVerify = (factor: PhoneEnrollmentFactor, automaticallySendSmsCode: boolean) => {
7
7
  const [code, setCode] = useState('')
8
+ const [sendingCode, setSendingCode] = useState(false)
8
9
  const [verifying, setVerifying] = useState(false)
9
10
  const [error, setError] = useState('')
10
11
 
@@ -15,14 +16,22 @@ export const usePhoneVerify = (factor: PhoneEnrollmentFactor, automaticallySendS
15
16
 
16
17
  const initSendCode = useRef(!!automaticallySendSmsCode)
17
18
 
18
- const { showSuccess, showError, showInfo } = useToast()
19
+ const { showSuccess, showError } = useToast()
19
20
 
20
21
  const sendCode = useCallback(async () => {
21
22
  if (!enrollmentFactors) {
22
23
  showError('Error - No session found')
23
24
  return
24
25
  }
25
- await auth.sendMultiFactorCode(factor, enrollmentFactors.multiFactorResolver)
26
+ setSendingCode(true)
27
+ return auth.sendMultiFactorCode(factor, enrollmentFactors.multiFactorResolver)
28
+ .then(() => {
29
+ setSendingCode(false)
30
+ })
31
+ .catch((e) => {
32
+ setSendingCode(false)
33
+ setError(e.message || 'An error occurred')
34
+ })
26
35
  }, [auth, factor, twoFactorVerification, showError])
27
36
 
28
37
  const initSendCodeFunc = useRef(sendCode)
@@ -32,7 +41,7 @@ export const usePhoneVerify = (factor: PhoneEnrollmentFactor, automaticallySendS
32
41
  }
33
42
  }, [])
34
43
 
35
- const handleVerify = useCallback(() => {
44
+ const handleVerify = useCallback(async () => {
36
45
  setVerifying(true)
37
46
  setError('')
38
47
  if (!twoFactorVerification) {
@@ -54,7 +63,7 @@ export const usePhoneVerify = (factor: PhoneEnrollmentFactor, automaticallySendS
54
63
  showError('Error - Two factor verification is not supported')
55
64
  return
56
65
  }
57
- verify(twoFactorVerification, code)
66
+ return verify(twoFactorVerification, code)
58
67
  .then(() => {
59
68
  setVerifying(false)
60
69
  setCode('')
@@ -69,7 +78,9 @@ export const usePhoneVerify = (factor: PhoneEnrollmentFactor, automaticallySendS
69
78
  return {
70
79
  code,
71
80
  setCode,
81
+ sendCode,
72
82
  verifying,
83
+ sendingCode,
73
84
  error,
74
85
  handleVerify,
75
86
  }
@@ -1,4 +1,5 @@
1
1
  import { BaseAuthProvider, GoogleAuthProvider } from '@chem-po/core'
2
+ import { Platform } from 'react-native'
2
3
 
3
4
  interface ValidationResult {
4
5
  isValid: boolean
@@ -27,6 +28,12 @@ export const validateAuthConfiguration = (providers: BaseAuthProvider[]): Valida
27
28
  'Google webClientId format looks incorrect. Expected format: "xxx.apps.googleusercontent.com"',
28
29
  )
29
30
  }
31
+ if (Platform.OS === 'ios' && !googleProvider.iosClientId) {
32
+ errors.push(
33
+ 'Google provider is missing iosClientId. ' +
34
+ 'Get this from Firebase Console > Authentication > Sign-in method > Google > iOS SDK configuration',
35
+ )
36
+ }
30
37
  }
31
38
 
32
39
  // Check environment